4 https://bugzilla.mozilla.org/show_bug.cgi?id=816720
7 <title>Test for Bug
816720</title>
8 <script 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>
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 }
26 <p><span id=control-decimal
></span></p>
27 <p><span id=control-cjk-decimal
></span></p>
28 <p><span id=test-counter-style
></span></p>
31 #control-decimal::before { content: counter(a, decimal); }
32 #control-cjk-decimal::before { content: counter(a, cjk-decimal); }
33 #test-counter-style::before { content: counter(a, unlikely-counter-style); }
36 <script type=
"application/javascript">
38 // Monospace fonts available on all the platforms we're testing on.
40 // XXX Once bug
817220 is fixed we could instead use the value of
41 // font.name.monospace.x-western as the monospace font to use.
42 var MONOSPACE_FONTS = [
50 var test = document.getElementById(
"test");
51 var controlSerif = document.getElementById(
"control-serif");
52 var controlMonospace = document.getElementById(
"control-monospace");
53 var testFont = document.getElementById(
"test-font");
54 var otherStyles = document.getElementById(
"other-styles");
56 otherStyles.sheet.insertRule(
"#control-monospace { font: 16px " +
57 MONOSPACE_FONTS +
", serif }",
0);
59 var monospaceWidth = controlMonospace.getBoundingClientRect().width;
60 var serifWidth = controlSerif.getBoundingClientRect().width;
62 var controlDecimal = document.getElementById(
"control-decimal");
63 var controlCJKDecimal = document.getElementById(
"control-cjk-decimal");
64 var testCounterStyle = document.getElementById(
"test-counter-style");
66 var decimalWidth = controlDecimal.getBoundingClientRect().width;
67 var cjkDecimalWidth = controlCJKDecimal.getBoundingClientRect().width;
69 // [at-rule type, passing condition, failing condition]
71 [
"@media",
"all",
"not all"],
72 [
"@supports",
"(color: green)",
"(unknown: unknown)"]
75 // [rule, function to test whether the rule was successfully inserted and applied]
77 [
"#test { text-decoration: underline; }",
78 function(aApplied, aParent, aException) {
80 window.getComputedStyle(test).textDecorationLine ==
81 (aApplied ?
"underline" :
"none");
83 [
"@page { margin: 4cm; }",
84 function(aApplied, aParent, aException) {
85 // just test whether it threw
88 [
"@keyframes test { from { font-size: 100px; } to { font-size: 100px; } }",
89 function(aApplied, aParent, aException) {
91 window.getComputedStyle(test).fontSize ==
92 (aApplied ?
"100px" :
"16px")
94 [
"@font-face { font-family: UnlikelyFontName; src: " +
95 MONOSPACE_FONTS.map(function(s) { return
"local('" + s +
"')" }).join(
", ") +
"; }",
96 function(aApplied, aParent, aException) {
97 var width = testFont.getBoundingClientRect().width;
101 if (navigator.oscpu.match(/Linux/) ||
102 navigator.oscpu.match(/Android/) ||
103 SpecialPowers.Services.appinfo.name ==
"B2G") {
106 return Math.abs(width - (aApplied ? monospaceWidth : serifWidth)) <=
1; // bug
769194 prevents local()
107 // fonts working on Android
109 [
"@import url(nothing.css);",
110 function(aApplied, aParent, aException) {
111 // just test whether it threw
112 return aParent instanceof CSSRule ? aException : !aException;
114 [
"@namespace test url(http://example.org);",
115 function(aApplied, aParent, aException) {
116 // just test whether it threw
117 return aParent instanceof CSSRule ? aException : !aException;
119 [
"@counter-style unlikely-counter-style { system: extends cjk-decimal; }",
120 function (aApplied, aParent, aException) {
121 var width = testCounterStyle.getBoundingClientRect().width;
125 return width == (aApplied ? cjkDecimalWidth : decimalWidth);
131 // First, assert that our assumed available fonts are indeed available
132 // and have expected metrics.
133 ok(monospaceWidth
> 0,
"monospace text has width");
134 ok(serifWidth
> 0,
"serif text has width");
135 ok(Math.abs(monospaceWidth - serifWidth)
> 1,
"monospace and serif text have sufficiently different widths");
137 // And that the #test-font element starts off using the
"serif" font.
138 var initialFontTestWidth = testFont.getBoundingClientRect().width;
139 is(initialFontTestWidth, serifWidth);
141 ok(decimalWidth
> 0,
"decimal counter has width");
142 ok(cjkDecimalWidth
> 0,
"cjk-decimal counter has width");
143 ok(decimalWidth != cjkDecimalWidth,
"decimal and cjk-decimal counter have different width")
145 var initialCounterStyleWidth = testCounterStyle.getBoundingClientRect().width;
146 is(initialCounterStyleWidth, decimalWidth,
"initial counter style is decimal");
148 // We construct a style sheet with zero, one or two levels of conditional
149 // grouping rules (taken from outerRuleInfo), with one of the inner rules
150 // at the deepest level.
151 var style = document.getElementById(
"style");
153 // For each of the outer rule types...
154 for (var outerRule1 =
0; outerRule1 < outerRuleInfo.length; outerRule1++) {
155 // For each of {
0 = don't create an outer rule,
156 //
1 = create an outer rule with a passing condition,
157 //
2 = create an outer rule with a failing condition }...
158 for (var outerRuleCondition1 =
0; outerRuleCondition1 <=
2; outerRuleCondition1++) {
160 // For each of the outer rule types again...
161 for (var outerRule2 =
0; outerRule2 < outerRuleInfo.length; outerRule2++) {
162 // For each of {
0 = don't create an outer rule,
163 //
1 = create an outer rule with a passing condition,
164 //
2 = create an outer rule with a failing condition } again...
165 for (var outerRuleCondition2 =
0; outerRuleCondition2 <=
2; outerRuleCondition2++) {
167 // For each of the inner rule types...
168 for (var innerRule =
0; innerRule < innerRuleInfo.length; innerRule++) {
171 var object = style.sheet;
172 while (object.cssRules.length) {
173 object.deleteRule(
0);
176 // We'll record whether the inner rule should have been applied,
177 // according to whether we put passing or failing conditional
178 // grouping rules around it.
181 if (outerRuleCondition1) {
182 // Create an outer conditional rule.
183 object.insertRule([outerRuleInfo[outerRule1][
0],
184 outerRuleInfo[outerRule1][outerRuleCondition1],
186 object = object.cssRules[
0];
188 if (outerRuleCondition1 ==
2) {
189 // If we used a failing condition, we don't expect the inner
190 // rule to be applied.
195 if (outerRuleCondition2) {
196 // Create another outer conditional rule as a child of the first
197 // outer conditional rule (or the style sheet, if we didn't create
198 // a first outer conditional rule).
199 object.insertRule([outerRuleInfo[outerRule2][
0],
200 outerRuleInfo[outerRule2][outerRuleCondition2],
202 object = object.cssRules[
0];
204 if (outerRuleCondition2 ==
2) {
205 // If we used a failing condition, we don't expect the inner
206 // rule to be applied.
211 var outer = object instanceof CSSRule ? object.cssText :
"style sheet";
212 var inner = innerRuleInfo[innerRule][
0];
214 // Insert the inner rule.
215 var exception = null;
217 object.insertRule(inner,
0);
222 ok(innerRuleInfo[innerRule][
1](applied, object, exception),
223 "<" + [outerRule1, outerRuleCondition1, outerRule2,
224 outerRuleCondition2, innerRule].join(
",") +
"> " +
225 "inserting " + inner +
" into " + outer.replace(/ *\n */g, ' '));
235 SimpleTest.waitForExplicitFinish();