<!DOCTYPE HTML> <html> <!-- --> <head> <title>Test for computation of values in property database</title> <script type="text/javascript" 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"> var numAssertions = 9; // these are from the additional margin-inline-{start,end} tests numAssertions += 2; SimpleTest.expectAssertions(numAssertions); SimpleTest.waitForExplicitFinish(); SimpleTest.requestLongerTimeout(2); var load_count = 0; function load_done() { if (++load_count == 3) run_tests(); } </script> </head> <body> <p id="display"><span><span id="elementf"></span></span> <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> <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 gBadComputed = { // These values are treated as auto. "page-break-after": [ "avoid" ], "page-break-before": [ "avoid" ], // This is the only SVG-length property (i.e., length allowing // unitless lengths) whose initial value is zero. "stroke-dashoffset": [ "0", "-moz-objectValue" ], }; 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 ((property in gBadComputed) && gBadComputed[property].indexOf(value) != -1) return true; if (!has_frame && (property in gBadComputedNoFrame) && gBadComputedNoFrame[property].indexOf(value) != -1) 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" ], }; function swap_when_frame(property, value) { return (property in gSwapInitialWhenHaveFrame) && gSwapInitialWhenHaveFrame[property].indexOf(value) != -1; } 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's important for values that are supposed to compute to the // initial value (given the current design of 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'll have a cached aStartStruct from the parent in the rule // tree (caching the "other" value), so we'll make sure we don't get // the initial value from the luck of default-initialization. // This means that it's important that we set the prereqs on // gRule1.style rather than on gElement.style. 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); } // FIXME: Something (maybe with the -moz-binding values) causes // gElementF's frame to get lost. Force it to get recreated after // each property. gElementF.parentNode.style.display = "none"; get_computed_value(getComputedStyle(gElementF, ""), "width"); gElementF.parentNode.style.display = ""; get_computed_value(getComputedStyle(gElementF, ""), "width"); } 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>