1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/layout/style/test/test_value_computation.html Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,255 @@ 1.4 +<!DOCTYPE HTML> 1.5 +<html> 1.6 +<!-- 1.7 +--> 1.8 +<head> 1.9 + <title>Test for computation of values in property database</title> 1.10 + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> 1.11 + <script type="text/javascript" src="property_database.js"></script> 1.12 + <style type="text/css" id="stylesheet"></style> 1.13 + <style type="text/css"> 1.14 + /* For 'width', 'height', etc., need a constant size container. */ 1.15 + #display { width: 500px; height: 200px } 1.16 + </style> 1.17 + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> 1.18 + <script type="text/javascript"> 1.19 + SimpleTest.expectAssertions(9); 1.20 + SimpleTest.waitForExplicitFinish(); 1.21 + SimpleTest.requestLongerTimeout(2); 1.22 + 1.23 + var load_count = 0; 1.24 + function load_done() { 1.25 + if (++load_count == 3) 1.26 + run_tests(); 1.27 + } 1.28 + </script> 1.29 +</head> 1.30 +<body> 1.31 +<p id="display"><span><span id="elementf"></span></span> 1.32 +<iframe id="unstyledn" src="unstyled.xml" height="10" width="10" onload="load_done()"></iframe> 1.33 +<iframe id="unstyledf" src="unstyled-frame.xml" height="10" width="10" onload="load_done()"></iframe> 1.34 +</p> 1.35 +<div id="content" style="display: none"> 1.36 + 1.37 +<div><span id="elementn"></span></div> 1.38 + 1.39 + 1.40 +</div> 1.41 +<pre id="test"> 1.42 +<script class="testbody" type="text/javascript"> 1.43 + 1.44 +/** Test for computation of values in property database **/ 1.45 + 1.46 +var gBadComputed = { 1.47 + // The CSS parser will accept these weird URLs. However, we'll fail to 1.48 + // resolve them when computing style, so we'll fall back to the initial 1.49 + // value ("none"). 1.50 + "filter": [ "url('feed:javascript:5')", "blur(3px) url('feed:javascript:5') grayscale(50%)" ], 1.51 + 1.52 + // These values are treated as auto. 1.53 + "page-break-after": [ "avoid" ], 1.54 + "page-break-before": [ "avoid" ], 1.55 + 1.56 + // This is the only SVG-length property (i.e., length allowing 1.57 + // unitless lengths) whose initial value is zero. 1.58 + "stroke-dashoffset": [ "0", "-moz-objectValue" ], 1.59 +}; 1.60 + 1.61 +var gBadComputedNoFrame = { 1.62 + // These are probably bogus tests... 1.63 + "border-radius": [ "0%", "calc(-1%)", "calc(0px) calc(0pt) calc(0%) calc(0em)" ], 1.64 + "border-bottom-left-radius": [ "0%", "calc(-1%)" ], 1.65 + "border-bottom-right-radius": [ "0%", "calc(-1%)" ], 1.66 + "border-top-left-radius": [ "0%", "calc(-1%)" ], 1.67 + "border-top-right-radius": [ "0%", "calc(-1%)" ], 1.68 + "-moz-margin-end": [ "0%", "calc(0% + 0px)", "calc(-1%)" ], 1.69 + "-moz-margin-start": [ "0%", "calc(0% + 0px)", "calc(-1%)" ], 1.70 + "-moz-outline-radius": [ "0%", "calc(-1%)", "calc(0px) calc(0pt) calc(0%) calc(0em)" ], 1.71 + "-moz-outline-radius-bottomleft": [ "0%", "calc(-1%)" ], 1.72 + "-moz-outline-radius-bottomright": [ "0%", "calc(-1%)" ], 1.73 + "-moz-outline-radius-topleft": [ "0%", "calc(-1%)" ], 1.74 + "-moz-outline-radius-topright": [ "0%", "calc(-1%)" ], 1.75 + "-moz-padding-end": [ "0%", "calc(0% + 0px)", "calc(-1%)" ], 1.76 + "-moz-padding-start": [ "0%", "calc(0% + 0px)", "calc(-1%)" ], 1.77 + "margin": [ "0% 0px 0em 0pt" ], 1.78 + "margin-bottom": [ "0%", "calc(0% + 0px)" ], 1.79 + "margin-left": [ "0%", "calc(0% + 0px)" ], 1.80 + "margin-right": [ "0%", "calc(0% + 0px)" ], 1.81 + "margin-top": [ "0%", "calc(0% + 0px)" ], 1.82 + "min-height": [ "calc(-1%)" ], 1.83 + "min-width": [ "calc(-1%)" ], 1.84 + "padding": [ "0% 0px 0em 0pt", "calc(0px) calc(0em) calc(-2px) calc(-1%)" ], 1.85 + "padding-bottom": [ "0%", "calc(0% + 0px)", "calc(-1%)" ], 1.86 + "padding-left": [ "0%", "calc(0% + 0px)", "calc(-1%)" ], 1.87 + "padding-right": [ "0%", "calc(0% + 0px)", "calc(-1%)" ], 1.88 + "padding-top": [ "0%", "calc(0% + 0px)", "calc(-1%)" ], 1.89 +}; 1.90 + 1.91 +function xfail_value(property, value, is_initial, has_frame) { 1.92 + if ((property in gBadComputed) && 1.93 + gBadComputed[property].indexOf(value) != -1) 1.94 + return true; 1.95 + 1.96 + if (!has_frame && (property in gBadComputedNoFrame) && 1.97 + gBadComputedNoFrame[property].indexOf(value) != -1) 1.98 + return true; 1.99 + 1.100 + return false; 1.101 +} 1.102 + 1.103 +var gSwapInitialWhenHaveFrame = { 1.104 + // When there's a frame, '-moz-available' works out to the same as 1.105 + // 'auto' given the prerequisites of only 'display: block'. 1.106 + "width": [ "-moz-available" ], 1.107 +}; 1.108 + 1.109 +function swap_when_frame(property, value) { 1.110 + return (property in gSwapInitialWhenHaveFrame) && 1.111 + gSwapInitialWhenHaveFrame[property].indexOf(value) != -1; 1.112 +} 1.113 + 1.114 +var gElementN = document.getElementById("elementn"); 1.115 +var gElementF = document.getElementById("elementf"); 1.116 +var gStyleSheet = document.getElementById("stylesheet").sheet; 1.117 +var gRule1 = gStyleSheet.cssRules[gStyleSheet.insertRule("#elementn, #elementf {}", gStyleSheet.cssRules.length)]; 1.118 +var gRule2 = gStyleSheet.cssRules[gStyleSheet.insertRule("#elementn, #elementf {}", gStyleSheet.cssRules.length)]; 1.119 + 1.120 +var gInitialValuesN; 1.121 +var gInitialValuesF; 1.122 +var gInitialPrereqsRuleN; 1.123 +var gInitialPrereqsRuleF; 1.124 + 1.125 +function setup_initial_values(id, ivalprop, prereqprop) { 1.126 + var iframe = document.getElementById(id); 1.127 + window[ivalprop] = iframe.contentWindow.getComputedStyle( 1.128 + iframe.contentDocument.documentElement.firstChild, ""); 1.129 + var sheet = iframe.contentDocument.styleSheets[0]; 1.130 + // For 'width', 'height', etc., need a constant size container. 1.131 + sheet.insertRule(":root { height: 200px; width: 500px }", sheet.cssRules.length); 1.132 + 1.133 + window[prereqprop] = sheet.cssRules[sheet.insertRule(":root > * {}", sheet.cssRules.length)]; 1.134 +} 1.135 + 1.136 +function test_value(property, val, is_initial) 1.137 +{ 1.138 + var info = gCSSProperties[property]; 1.139 + if (info.backend_only) 1.140 + return; 1.141 + 1.142 + if ("prerequisites" in info) { 1.143 + var prereqs = info.prerequisites; 1.144 + for (var prereq in prereqs) { 1.145 + gRule1.style.setProperty(prereq, prereqs[prereq], ""); 1.146 + gInitialPrereqsRuleN.style.setProperty(prereq, prereqs[prereq], ""); 1.147 + gInitialPrereqsRuleF.style.setProperty(prereq, prereqs[prereq], ""); 1.148 + } 1.149 + } 1.150 + if (info.inherited && is_initial) { 1.151 + gElementN.parentNode.style.setProperty(property, info.other_values[0], ""); 1.152 + gElementF.parentNode.style.setProperty(property, info.other_values[0], ""); 1.153 + } 1.154 + 1.155 + var initial_computed_n = get_computed_value(gInitialValuesN, property); 1.156 + var initial_computed_f = get_computed_value(gInitialValuesF, property); 1.157 + if (is_initial) { 1.158 + gRule1.style.setProperty(property, info.other_values[0], ""); 1.159 + var other_computed_n = get_computed_value(getComputedStyle(gElementN, ""), property); 1.160 + var other_computed_f = get_computed_value(getComputedStyle(gElementF, ""), property); 1.161 + isnot(other_computed_n, initial_computed_n, 1.162 + "should be testing with values that compute to different things " + 1.163 + "for '" + property + "'"); 1.164 + isnot(other_computed_f, initial_computed_f, 1.165 + "should be testing with values that compute to different things " + 1.166 + "for '" + property + "'"); 1.167 + } 1.168 + // It's important for values that are supposed to compute to the 1.169 + // initial value (given the current design of nsRuleNode) that we're 1.170 + // modifying the most specific rule that matches the element, and that 1.171 + // we've already requested style while that rule was empty. This 1.172 + // means we'll have a cached aStartStruct from the parent in the rule 1.173 + // tree (caching the "other" value), so we'll make sure we don't get 1.174 + // the initial value from the luck of default-initialization. 1.175 + // This means that it's important that we set the prereqs on 1.176 + // gRule1.style rather than on gElement.style. 1.177 + gRule2.style.setProperty(property, val, ""); 1.178 + var val_computed_n = get_computed_value(getComputedStyle(gElementN, ""), property); 1.179 + var val_computed_f = get_computed_value(getComputedStyle(gElementF, ""), property); 1.180 + isnot(val_computed_n, "", 1.181 + "should not get empty value for '" + property + ":" + val + "'"); 1.182 + isnot(val_computed_f, "", 1.183 + "should not get empty value for '" + property + ":" + val + "'"); 1.184 + if (is_initial) { 1.185 + (xfail_value(property, val, is_initial, false) ? todo_is : is)( 1.186 + val_computed_n, initial_computed_n, 1.187 + "should get initial value for '" + property + ":" + val + "'"); 1.188 + (xfail_value(property, val, is_initial, true) ? todo_is : is)( 1.189 + val_computed_f, initial_computed_f, 1.190 + "should get initial value for '" + property + ":" + val + "'"); 1.191 + } else { 1.192 + (xfail_value(property, val, is_initial, false) ? todo_isnot : isnot)( 1.193 + val_computed_n, initial_computed_n, 1.194 + "should not get initial value for '" + property + ":" + val + "' on elementn."); 1.195 + var swap = swap_when_frame(property, val); 1.196 + (xfail_value(property, val, is_initial, true) ? todo_isnot : (swap ? is : isnot))( 1.197 + val_computed_f, initial_computed_f, 1.198 + "should " + (swap ? "" : "not ") + 1.199 + "get initial value for '" + property + ":" + val + "' on elementf."); 1.200 + } 1.201 + if (is_initial) 1.202 + gRule1.style.removeProperty(property); 1.203 + gRule2.style.removeProperty(property); 1.204 + 1.205 + if ("prerequisites" in info) { 1.206 + var prereqs = info.prerequisites; 1.207 + for (var prereq in prereqs) { 1.208 + gRule1.style.removeProperty(prereq); 1.209 + gInitialPrereqsRuleN.style.removeProperty(prereq); 1.210 + gInitialPrereqsRuleF.style.removeProperty(prereq); 1.211 + } 1.212 + } 1.213 + if (info.inherited && is_initial) { 1.214 + gElementN.parentNode.style.removeProperty(property); 1.215 + gElementF.parentNode.style.removeProperty(property); 1.216 + } 1.217 + 1.218 + // FIXME: Something (maybe with the -moz-binding values) causes 1.219 + // gElementF's frame to get lost. Force it to get recreated after 1.220 + // each property. 1.221 + gElementF.parentNode.style.display = "none"; 1.222 + get_computed_value(getComputedStyle(gElementF, ""), "width"); 1.223 + gElementF.parentNode.style.display = ""; 1.224 + get_computed_value(getComputedStyle(gElementF, ""), "width"); 1.225 +} 1.226 + 1.227 +function test_property(prop) { 1.228 + var info = gCSSProperties[prop]; 1.229 + for (var idx in info.initial_values) 1.230 + test_value(prop, info.initial_values[idx], true); 1.231 + for (var idx in info.other_values) 1.232 + test_value(prop, info.other_values[idx], false); 1.233 +} 1.234 + 1.235 +function run_tests() { 1.236 + setup_initial_values("unstyledn", "gInitialValuesN", "gInitialPrereqsRuleN"); 1.237 + setup_initial_values("unstyledf", "gInitialValuesF", "gInitialPrereqsRuleF"); 1.238 + var props = []; 1.239 + for (var prop in gCSSProperties) 1.240 + props.push(prop); 1.241 + props = props.reverse(); 1.242 + function do_one() { 1.243 + if (props.length == 0) { 1.244 + SimpleTest.finish(); 1.245 + return; 1.246 + } 1.247 + test_property(props.pop()); 1.248 + SimpleTest.executeSoon(do_one); 1.249 + } 1.250 + SimpleTest.executeSoon(do_one); 1.251 +} 1.252 + 1.253 +load_done(); 1.254 + 1.255 +</script> 1.256 +</pre> 1.257 +</body> 1.258 +</html>