Wed, 31 Dec 2014 13:27:57 +0100
Ignore runtime configuration files generated during quality assurance.
1 <!DOCTYPE HTML>
2 <html>
3 <!--
4 -->
5 <head>
6 <title>Test for computation of values in property database</title>
7 <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
8 <script type="text/javascript" src="property_database.js"></script>
9 <style type="text/css" id="stylesheet"></style>
10 <style type="text/css">
11 /* For 'width', 'height', etc., need a constant size container. */
12 #display { width: 500px; height: 200px }
13 </style>
14 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
15 <script type="text/javascript">
16 SimpleTest.expectAssertions(9);
17 SimpleTest.waitForExplicitFinish();
18 SimpleTest.requestLongerTimeout(2);
20 var load_count = 0;
21 function load_done() {
22 if (++load_count == 3)
23 run_tests();
24 }
25 </script>
26 </head>
27 <body>
28 <p id="display"><span><span id="elementf"></span></span>
29 <iframe id="unstyledn" src="unstyled.xml" height="10" width="10" onload="load_done()"></iframe>
30 <iframe id="unstyledf" src="unstyled-frame.xml" height="10" width="10" onload="load_done()"></iframe>
31 </p>
32 <div id="content" style="display: none">
34 <div><span id="elementn"></span></div>
37 </div>
38 <pre id="test">
39 <script class="testbody" type="text/javascript">
41 /** Test for computation of values in property database **/
43 var gBadComputed = {
44 // The CSS parser will accept these weird URLs. However, we'll fail to
45 // resolve them when computing style, so we'll fall back to the initial
46 // value ("none").
47 "filter": [ "url('feed:javascript:5')", "blur(3px) url('feed:javascript:5') grayscale(50%)" ],
49 // These values are treated as auto.
50 "page-break-after": [ "avoid" ],
51 "page-break-before": [ "avoid" ],
53 // This is the only SVG-length property (i.e., length allowing
54 // unitless lengths) whose initial value is zero.
55 "stroke-dashoffset": [ "0", "-moz-objectValue" ],
56 };
58 var gBadComputedNoFrame = {
59 // These are probably bogus tests...
60 "border-radius": [ "0%", "calc(-1%)", "calc(0px) calc(0pt) calc(0%) calc(0em)" ],
61 "border-bottom-left-radius": [ "0%", "calc(-1%)" ],
62 "border-bottom-right-radius": [ "0%", "calc(-1%)" ],
63 "border-top-left-radius": [ "0%", "calc(-1%)" ],
64 "border-top-right-radius": [ "0%", "calc(-1%)" ],
65 "-moz-margin-end": [ "0%", "calc(0% + 0px)", "calc(-1%)" ],
66 "-moz-margin-start": [ "0%", "calc(0% + 0px)", "calc(-1%)" ],
67 "-moz-outline-radius": [ "0%", "calc(-1%)", "calc(0px) calc(0pt) calc(0%) calc(0em)" ],
68 "-moz-outline-radius-bottomleft": [ "0%", "calc(-1%)" ],
69 "-moz-outline-radius-bottomright": [ "0%", "calc(-1%)" ],
70 "-moz-outline-radius-topleft": [ "0%", "calc(-1%)" ],
71 "-moz-outline-radius-topright": [ "0%", "calc(-1%)" ],
72 "-moz-padding-end": [ "0%", "calc(0% + 0px)", "calc(-1%)" ],
73 "-moz-padding-start": [ "0%", "calc(0% + 0px)", "calc(-1%)" ],
74 "margin": [ "0% 0px 0em 0pt" ],
75 "margin-bottom": [ "0%", "calc(0% + 0px)" ],
76 "margin-left": [ "0%", "calc(0% + 0px)" ],
77 "margin-right": [ "0%", "calc(0% + 0px)" ],
78 "margin-top": [ "0%", "calc(0% + 0px)" ],
79 "min-height": [ "calc(-1%)" ],
80 "min-width": [ "calc(-1%)" ],
81 "padding": [ "0% 0px 0em 0pt", "calc(0px) calc(0em) calc(-2px) calc(-1%)" ],
82 "padding-bottom": [ "0%", "calc(0% + 0px)", "calc(-1%)" ],
83 "padding-left": [ "0%", "calc(0% + 0px)", "calc(-1%)" ],
84 "padding-right": [ "0%", "calc(0% + 0px)", "calc(-1%)" ],
85 "padding-top": [ "0%", "calc(0% + 0px)", "calc(-1%)" ],
86 };
88 function xfail_value(property, value, is_initial, has_frame) {
89 if ((property in gBadComputed) &&
90 gBadComputed[property].indexOf(value) != -1)
91 return true;
93 if (!has_frame && (property in gBadComputedNoFrame) &&
94 gBadComputedNoFrame[property].indexOf(value) != -1)
95 return true;
97 return false;
98 }
100 var gSwapInitialWhenHaveFrame = {
101 // When there's a frame, '-moz-available' works out to the same as
102 // 'auto' given the prerequisites of only 'display: block'.
103 "width": [ "-moz-available" ],
104 };
106 function swap_when_frame(property, value) {
107 return (property in gSwapInitialWhenHaveFrame) &&
108 gSwapInitialWhenHaveFrame[property].indexOf(value) != -1;
109 }
111 var gElementN = document.getElementById("elementn");
112 var gElementF = document.getElementById("elementf");
113 var gStyleSheet = document.getElementById("stylesheet").sheet;
114 var gRule1 = gStyleSheet.cssRules[gStyleSheet.insertRule("#elementn, #elementf {}", gStyleSheet.cssRules.length)];
115 var gRule2 = gStyleSheet.cssRules[gStyleSheet.insertRule("#elementn, #elementf {}", gStyleSheet.cssRules.length)];
117 var gInitialValuesN;
118 var gInitialValuesF;
119 var gInitialPrereqsRuleN;
120 var gInitialPrereqsRuleF;
122 function setup_initial_values(id, ivalprop, prereqprop) {
123 var iframe = document.getElementById(id);
124 window[ivalprop] = iframe.contentWindow.getComputedStyle(
125 iframe.contentDocument.documentElement.firstChild, "");
126 var sheet = iframe.contentDocument.styleSheets[0];
127 // For 'width', 'height', etc., need a constant size container.
128 sheet.insertRule(":root { height: 200px; width: 500px }", sheet.cssRules.length);
130 window[prereqprop] = sheet.cssRules[sheet.insertRule(":root > * {}", sheet.cssRules.length)];
131 }
133 function test_value(property, val, is_initial)
134 {
135 var info = gCSSProperties[property];
136 if (info.backend_only)
137 return;
139 if ("prerequisites" in info) {
140 var prereqs = info.prerequisites;
141 for (var prereq in prereqs) {
142 gRule1.style.setProperty(prereq, prereqs[prereq], "");
143 gInitialPrereqsRuleN.style.setProperty(prereq, prereqs[prereq], "");
144 gInitialPrereqsRuleF.style.setProperty(prereq, prereqs[prereq], "");
145 }
146 }
147 if (info.inherited && is_initial) {
148 gElementN.parentNode.style.setProperty(property, info.other_values[0], "");
149 gElementF.parentNode.style.setProperty(property, info.other_values[0], "");
150 }
152 var initial_computed_n = get_computed_value(gInitialValuesN, property);
153 var initial_computed_f = get_computed_value(gInitialValuesF, property);
154 if (is_initial) {
155 gRule1.style.setProperty(property, info.other_values[0], "");
156 var other_computed_n = get_computed_value(getComputedStyle(gElementN, ""), property);
157 var other_computed_f = get_computed_value(getComputedStyle(gElementF, ""), property);
158 isnot(other_computed_n, initial_computed_n,
159 "should be testing with values that compute to different things " +
160 "for '" + property + "'");
161 isnot(other_computed_f, initial_computed_f,
162 "should be testing with values that compute to different things " +
163 "for '" + property + "'");
164 }
165 // It's important for values that are supposed to compute to the
166 // initial value (given the current design of nsRuleNode) that we're
167 // modifying the most specific rule that matches the element, and that
168 // we've already requested style while that rule was empty. This
169 // means we'll have a cached aStartStruct from the parent in the rule
170 // tree (caching the "other" value), so we'll make sure we don't get
171 // the initial value from the luck of default-initialization.
172 // This means that it's important that we set the prereqs on
173 // gRule1.style rather than on gElement.style.
174 gRule2.style.setProperty(property, val, "");
175 var val_computed_n = get_computed_value(getComputedStyle(gElementN, ""), property);
176 var val_computed_f = get_computed_value(getComputedStyle(gElementF, ""), property);
177 isnot(val_computed_n, "",
178 "should not get empty value for '" + property + ":" + val + "'");
179 isnot(val_computed_f, "",
180 "should not get empty value for '" + property + ":" + val + "'");
181 if (is_initial) {
182 (xfail_value(property, val, is_initial, false) ? todo_is : is)(
183 val_computed_n, initial_computed_n,
184 "should get initial value for '" + property + ":" + val + "'");
185 (xfail_value(property, val, is_initial, true) ? todo_is : is)(
186 val_computed_f, initial_computed_f,
187 "should get initial value for '" + property + ":" + val + "'");
188 } else {
189 (xfail_value(property, val, is_initial, false) ? todo_isnot : isnot)(
190 val_computed_n, initial_computed_n,
191 "should not get initial value for '" + property + ":" + val + "' on elementn.");
192 var swap = swap_when_frame(property, val);
193 (xfail_value(property, val, is_initial, true) ? todo_isnot : (swap ? is : isnot))(
194 val_computed_f, initial_computed_f,
195 "should " + (swap ? "" : "not ") +
196 "get initial value for '" + property + ":" + val + "' on elementf.");
197 }
198 if (is_initial)
199 gRule1.style.removeProperty(property);
200 gRule2.style.removeProperty(property);
202 if ("prerequisites" in info) {
203 var prereqs = info.prerequisites;
204 for (var prereq in prereqs) {
205 gRule1.style.removeProperty(prereq);
206 gInitialPrereqsRuleN.style.removeProperty(prereq);
207 gInitialPrereqsRuleF.style.removeProperty(prereq);
208 }
209 }
210 if (info.inherited && is_initial) {
211 gElementN.parentNode.style.removeProperty(property);
212 gElementF.parentNode.style.removeProperty(property);
213 }
215 // FIXME: Something (maybe with the -moz-binding values) causes
216 // gElementF's frame to get lost. Force it to get recreated after
217 // each property.
218 gElementF.parentNode.style.display = "none";
219 get_computed_value(getComputedStyle(gElementF, ""), "width");
220 gElementF.parentNode.style.display = "";
221 get_computed_value(getComputedStyle(gElementF, ""), "width");
222 }
224 function test_property(prop) {
225 var info = gCSSProperties[prop];
226 for (var idx in info.initial_values)
227 test_value(prop, info.initial_values[idx], true);
228 for (var idx in info.other_values)
229 test_value(prop, info.other_values[idx], false);
230 }
232 function run_tests() {
233 setup_initial_values("unstyledn", "gInitialValuesN", "gInitialPrereqsRuleN");
234 setup_initial_values("unstyledf", "gInitialValuesF", "gInitialPrereqsRuleF");
235 var props = [];
236 for (var prop in gCSSProperties)
237 props.push(prop);
238 props = props.reverse();
239 function do_one() {
240 if (props.length == 0) {
241 SimpleTest.finish();
242 return;
243 }
244 test_property(props.pop());
245 SimpleTest.executeSoon(do_one);
246 }
247 SimpleTest.executeSoon(do_one);
248 }
250 load_done();
252 </script>
253 </pre>
254 </body>
255 </html>