diff options
Diffstat (limited to 'layout/style/test/test_value_computation.html')
-rw-r--r-- | layout/style/test/test_value_computation.html | 236 |
1 files changed, 236 insertions, 0 deletions
diff --git a/layout/style/test/test_value_computation.html b/layout/style/test/test_value_computation.html new file mode 100644 index 0000000000..df38a24b9b --- /dev/null +++ b/layout/style/test/test_value_computation.html @@ -0,0 +1,236 @@ +<!DOCTYPE HTML> +<html> +<!-- +--> +<head> + <title>Test for computation of values in property database</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="property_database.js"></script> + <style type="text/css" id="stylesheet"></style> + <style type="text/css"> + /* For 'width', 'height', etc., need a constant size container. */ + #display { width: 500px; height: 200px } + </style> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript"> + SimpleTest.waitForExplicitFinish(); + SimpleTest.requestLongerTimeout(2); + + var load_count = 0; + function load_done() { + if (++load_count == 3) + run_tests(); + } + </script> +</head> +<body> +<iframe id="unstyledn" src="unstyled.xml" height="10" width="10" onload="load_done()"></iframe> +<iframe id="unstyledf" src="unstyled-frame.xml" height="10" width="10" onload="load_done()"></iframe> +<p id="display"><span><span id="elementf"></span></span></p> +<div id="content" style="display: none"> + +<div><span id="elementn"></span></div> + + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for computation of values in property database **/ + +var gBadComputedNoFrame = { + // These are probably bogus tests... + "-moz-margin-end": [ "0%", "calc(0% + 0px)" ], + "-moz-margin-start": [ "0%", "calc(0% + 0px)" ], + "-moz-padding-end": [ "0%", "calc(0% + 0px)", "calc(-1%)" ], + "-moz-padding-start": [ "0%", "calc(0% + 0px)", "calc(-1%)" ], + "margin": [ "0% 0px 0em 0pt" ], + "margin-block-end": [ "0%", "calc(0% + 0px)" ], + "margin-block-start": [ "0%", "calc(0% + 0px)" ], + "margin-bottom": [ "0%", "calc(0% + 0px)" ], + "margin-inline-end": [ "0%", "calc(0% + 0px)" ], + "margin-inline-start": [ "0%", "calc(0% + 0px)" ], + "margin-left": [ "0%", "calc(0% + 0px)" ], + "margin-right": [ "0%", "calc(0% + 0px)" ], + "margin-top": [ "0%", "calc(0% + 0px)" ], + "padding": [ "0% 0px 0em 0pt", "calc(0px) calc(0em) calc(-2px) calc(-1%)" ], + "padding-block-end": [ "0%", "calc(0% + 0px)", "calc(-1%)" ], + "padding-block-start": [ "0%", "calc(0% + 0px)", "calc(-1%)" ], + "padding-bottom": [ "0%", "calc(0% + 0px)", "calc(-1%)" ], + "padding-inline-end": [ "0%", "calc(0% + 0px)", "calc(-1%)" ], + "padding-inline-start": [ "0%", "calc(0% + 0px)", "calc(-1%)" ], + "padding-left": [ "0%", "calc(0% + 0px)", "calc(-1%)" ], + "padding-right": [ "0%", "calc(0% + 0px)", "calc(-1%)" ], + "padding-top": [ "0%", "calc(0% + 0px)", "calc(-1%)" ], +}; + +function xfail_value(property, value, is_initial, has_frame) { + if (!has_frame && (property in gBadComputedNoFrame) && + gBadComputedNoFrame[property].includes(value)) + return true; + + return false; +} + +var gSwapInitialWhenHaveFrame = { + // When there's a frame, '-moz-available' works out to the same as + // 'auto' given the prerequisites of only 'display: block'. + "width": [ "-moz-available" ], + // When there's a frame, these keywords works out to the same as the initial + // value, i.e. `auto`, given the prerequisites of only 'display: block'. + "height": [ "-moz-max-content", "-moz-min-content", "-moz-fit-content", + "-moz-available", "max-content", "min-content", "fit-content", + "fit-content(100px)", "fit-content(10%)", + "fit-content(calc(3*25px + 50%))" ], + "block-size": [ "-moz-max-content", "-moz-min-content", "-moz-fit-content", + "-moz-available", "max-content", "min-content", "fit-content", + "fit-content(100px)", "fit-content(10%)", + "fit-content(calc(3*25px + 50%))" ], +}; + +function swap_when_frame(property, value) { + return (property in gSwapInitialWhenHaveFrame) && + gSwapInitialWhenHaveFrame[property].includes(value); +} + +var gDisplayTree = document.getElementById("display"); +var gElementN = document.getElementById("elementn"); +var gElementF = document.getElementById("elementf"); +var gStyleSheet = document.getElementById("stylesheet").sheet; +var gRule1 = gStyleSheet.cssRules[gStyleSheet.insertRule("#elementn, #elementf {}", gStyleSheet.cssRules.length)]; +var gRule2 = gStyleSheet.cssRules[gStyleSheet.insertRule("#elementn, #elementf {}", gStyleSheet.cssRules.length)]; + +var gInitialValuesN; +var gInitialValuesF; +var gInitialPrereqsRuleN; +var gInitialPrereqsRuleF; + +function setup_initial_values(id, ivalprop, prereqprop) { + var iframe = document.getElementById(id); + window[ivalprop] = iframe.contentWindow.getComputedStyle( + iframe.contentDocument.documentElement.firstChild); + var sheet = iframe.contentDocument.styleSheets[0]; + // For 'width', 'height', etc., need a constant size container. + sheet.insertRule(":root { height: 200px; width: 500px }", sheet.cssRules.length); + + window[prereqprop] = sheet.cssRules[sheet.insertRule(":root > * {}", sheet.cssRules.length)]; +} + +function test_value(property, val, is_initial) +{ + var info = gCSSProperties[property]; + + if ("prerequisites" in info) { + var prereqs = info.prerequisites; + for (var prereq in prereqs) { + gRule1.style.setProperty(prereq, prereqs[prereq], ""); + gInitialPrereqsRuleN.style.setProperty(prereq, prereqs[prereq], ""); + gInitialPrereqsRuleF.style.setProperty(prereq, prereqs[prereq], ""); + } + } + if (info.inherited && is_initial) { + gElementN.parentNode.style.setProperty(property, info.other_values[0], ""); + gElementF.parentNode.style.setProperty(property, info.other_values[0], ""); + } + + var initial_computed_n = get_computed_value(gInitialValuesN, property); + var initial_computed_f = get_computed_value(gInitialValuesF, property); + if (is_initial) { + gRule1.style.setProperty(property, info.other_values[0], ""); + var other_computed_n = get_computed_value(getComputedStyle(gElementN, ""), property); + var other_computed_f = get_computed_value(getComputedStyle(gElementF, ""), property); + isnot(other_computed_n, initial_computed_n, + "should be testing with values that compute to different things " + + "for '" + property + "'"); + isnot(other_computed_f, initial_computed_f, + "should be testing with values that compute to different things " + + "for '" + property + "'"); + } + // It used to be important for values that are supposed to compute to the + // initial value (given the design of the old rule tree, nsRuleNode) that + // we're modifying the most specific rule that matches the element, and + // that we've already requested style while that rule was empty. This + // means we'd have a cached aStartStruct from the parent in the rule + // tree (caching the "other" value), so we'd make sure we don't get the + // initial value from the luck of default-initialization. This means + // that it would've been important that we set the prereqs on + // gRule1.style rather than on gElement.style. + // + // However, the rule tree no longer stores cached structs, and we only + // temporarily cache reset structs during a single restyle. So the + // particular failure mode this was designed to test for isn't as + // likely to eventuate. + gRule2.style.setProperty(property, val, ""); + var val_computed_n = get_computed_value(getComputedStyle(gElementN, ""), property); + var val_computed_f = get_computed_value(getComputedStyle(gElementF, ""), property); + isnot(val_computed_n, "", + "should not get empty value for '" + property + ":" + val + "'"); + isnot(val_computed_f, "", + "should not get empty value for '" + property + ":" + val + "'"); + if (is_initial) { + (xfail_value(property, val, is_initial, false) ? todo_is : is)( + val_computed_n, initial_computed_n, + "should get initial value for '" + property + ":" + val + "'"); + (xfail_value(property, val, is_initial, true) ? todo_is : is)( + val_computed_f, initial_computed_f, + "should get initial value for '" + property + ":" + val + "'"); + } else { + (xfail_value(property, val, is_initial, false) ? todo_isnot : isnot)( + val_computed_n, initial_computed_n, + "should not get initial value for '" + property + ":" + val + "' on elementn."); + var swap = swap_when_frame(property, val); + (xfail_value(property, val, is_initial, true) ? todo_isnot : (swap ? is : isnot))( + val_computed_f, initial_computed_f, + "should " + (swap ? "" : "not ") + + "get initial value for '" + property + ":" + val + "' on elementf."); + } + if (is_initial) + gRule1.style.removeProperty(property); + gRule2.style.removeProperty(property); + + if ("prerequisites" in info) { + var prereqs = info.prerequisites; + for (var prereq in prereqs) { + gRule1.style.removeProperty(prereq); + gInitialPrereqsRuleN.style.removeProperty(prereq); + gInitialPrereqsRuleF.style.removeProperty(prereq); + } + } + if (info.inherited && is_initial) { + gElementN.parentNode.style.removeProperty(property); + gElementF.parentNode.style.removeProperty(property); + } +} + +function test_property(prop) { + var info = gCSSProperties[prop]; + for (var idx in info.initial_values) + test_value(prop, info.initial_values[idx], true); + for (var idx in info.other_values) + test_value(prop, info.other_values[idx], false); +} + +function run_tests() { + setup_initial_values("unstyledn", "gInitialValuesN", "gInitialPrereqsRuleN"); + setup_initial_values("unstyledf", "gInitialValuesF", "gInitialPrereqsRuleF"); + var props = []; + for (var prop in gCSSProperties) + props.push(prop); + props = props.reverse(); + function do_one() { + if (props.length == 0) { + SimpleTest.finish(); + return; + } + test_property(props.pop()); + SimpleTest.executeSoon(do_one); + } + SimpleTest.executeSoon(do_one); +} + +load_done(); + +</script> +</pre> +</body> +</html> |