layout/style/test/test_rule_insertion.html

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/layout/style/test/test_rule_insertion.html	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,214 @@
     1.4 +<!DOCTYPE HTML>
     1.5 +<html>
     1.6 +<!--
     1.7 +https://bugzilla.mozilla.org/show_bug.cgi?id=816720
     1.8 +-->
     1.9 +<head>
    1.10 +  <title>Test for Bug 816720</title>
    1.11 +  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
    1.12 +  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
    1.13 +  <style type="text/css" id="style"></style>
    1.14 +</head>
    1.15 +<body>
    1.16 +
    1.17 +<pre id="test"></pre>
    1.18 +
    1.19 +<p><span id=control-serif>........</span></p>
    1.20 +<p><span id=control-monospace>........</span></p>
    1.21 +<p><span id=test-font>........</span></p>
    1.22 +
    1.23 +<style id=other-styles>
    1.24 +  #test { font-size: 16px; animation: test 1s both }
    1.25 +  #control-serif { font: 16px serif }
    1.26 +  #test-font { font: 16px UnlikelyFontName, serif }
    1.27 +</style>
    1.28 +
    1.29 +<script type="application/javascript">
    1.30 +
    1.31 +// Monospace fonts available on all the platforms we're testing on.
    1.32 +//
    1.33 +// XXX Once bug 817220 is fixed we could instead use the value of
    1.34 +// font.name.monospace.x-western as the monospace font to use.
    1.35 +var MONOSPACE_FONTS = [
    1.36 +  "Courier",
    1.37 +  "Courier New",
    1.38 +  "Monaco",
    1.39 +  "DejaVu Sans Mono",
    1.40 +  "Droid Sans Mono"
    1.41 +];
    1.42 +
    1.43 +var test = document.getElementById("test");
    1.44 +var controlSerif = document.getElementById("control-serif");
    1.45 +var controlMonospace = document.getElementById("control-monospace");
    1.46 +var testFont = document.getElementById("test-font");
    1.47 +var otherStyles = document.getElementById("other-styles");
    1.48 +
    1.49 +otherStyles.sheet.insertRule("#control-monospace { font: 16px " +
    1.50 +                             MONOSPACE_FONTS + ", serif }", 0);
    1.51 +
    1.52 +var monospaceWidth = controlMonospace.getBoundingClientRect().width;
    1.53 +var serifWidth = controlSerif.getBoundingClientRect().width;
    1.54 +
    1.55 +// [at-rule type, passing condition, failing condition]
    1.56 +var outerRuleInfo = [
    1.57 +  ["@media", "all", "not all"],
    1.58 +  ["@-moz-document", "url-prefix('')", "url-prefix('zzz')"],
    1.59 +  ["@supports", "(color: green)", "(unknown: unknown)"]
    1.60 +];
    1.61 +
    1.62 +// [rule, function to test whether the rule was successfully inserted and applied]
    1.63 +var innerRuleInfo = [
    1.64 +  ["#test { text-decoration: underline; }",
    1.65 +   function(aApplied, aParent, aException) {
    1.66 +     return !aException &&
    1.67 +            window.getComputedStyle(test, "").textDecoration ==
    1.68 +               (aApplied ? "underline" : "none");
    1.69 +   }],
    1.70 +  ["@page { margin: 4cm; }",
    1.71 +   function(aApplied, aParent, aException) {
    1.72 +     // just test whether it threw
    1.73 +     return !aException;
    1.74 +   }],
    1.75 +  ["@keyframes test { from { font-size: 100px; } to { font-size: 100px; } }",
    1.76 +   function(aApplied, aParent, aException) {
    1.77 +     return !aException &&
    1.78 +            window.getComputedStyle(test, "").fontSize ==
    1.79 +                (aApplied ? "100px" : "16px")
    1.80 +   }],
    1.81 +  ["@font-face { font-family: UnlikelyFontName; src: " +
    1.82 +     MONOSPACE_FONTS.map(function(s) { return "local('" + s + "')" }).join(", ") + "; }",
    1.83 +   function(aApplied, aParent, aException) {
    1.84 +     var width = testFont.getBoundingClientRect().width;
    1.85 +     if (aException) {
    1.86 +       return false;
    1.87 +     }
    1.88 +     if (navigator.oscpu.match(/Linux/) ||
    1.89 +         navigator.oscpu.match(/Android/) ||
    1.90 +         SpecialPowers.Services.appinfo.name == "B2G") {
    1.91 +       return true;
    1.92 +    }
    1.93 +    return Math.abs(width - (aApplied ? monospaceWidth : serifWidth)) <= 1; // bug 769194 prevents local()
    1.94 +                                             // fonts working on Android
    1.95 +   }],
    1.96 +  ["@charset 'UTF-8';",
    1.97 +   function(aApplied, aParent, aException) {
    1.98 +     // just test whether it threw
    1.99 +     return aParent instanceof CSSRule ? aException : !aException;
   1.100 +   }],
   1.101 +  ["@import url(nothing.css);",
   1.102 +   function(aApplied, aParent, aException) {
   1.103 +     // just test whether it threw
   1.104 +     return aParent instanceof CSSRule ? aException : !aException;
   1.105 +   }],
   1.106 +  ["@namespace test url(http://example.org);",
   1.107 +   function(aApplied, aParent, aException) {
   1.108 +     // just test whether it threw
   1.109 +     return aParent instanceof CSSRule ? aException : !aException;
   1.110 +   }],
   1.111 +];
   1.112 +
   1.113 +function runTest()
   1.114 +{
   1.115 +  // First, assert that our assumed available fonts are indeed available
   1.116 +  // and have expected metrics.
   1.117 +  ok(monospaceWidth > 0, "monospace text has width");
   1.118 +  ok(serifWidth > 0, "serif text has width");
   1.119 +  ok(Math.abs(monospaceWidth - serifWidth) > 1, "monospace and serif text have sufficiently different widths");
   1.120 +
   1.121 +  // And that the #test-font element starts off using the "serif" font.
   1.122 +  var initialFontTestWidth = testFont.getBoundingClientRect().width;
   1.123 +  is(initialFontTestWidth, serifWidth);
   1.124 +
   1.125 +  // We construct a style sheet with zero, one or two levels of conditional
   1.126 +  // grouping rules (taken from outerRuleInfo), with one of the inner rules
   1.127 +  // at the deepest level.
   1.128 +  var style = document.getElementById("style");
   1.129 +
   1.130 +  // For each of the outer rule types...
   1.131 +  for (var outerRule1 = 0; outerRule1 < outerRuleInfo.length; outerRule1++) {
   1.132 +    // For each of { 0 = don't create an outer rule,
   1.133 +    //               1 = create an outer rule with a passing condition,
   1.134 +    //               2 = create an outer rule with a failing condition }...
   1.135 +    for (var outerRuleCondition1 = 0; outerRuleCondition1 <= 2; outerRuleCondition1++) {
   1.136 +
   1.137 +      // For each of the outer rule types again...
   1.138 +      for (var outerRule2 = 0; outerRule2 < outerRuleInfo.length; outerRule2++) {
   1.139 +        // For each of { 0 = don't create an outer rule,
   1.140 +        //               1 = create an outer rule with a passing condition,
   1.141 +        //               2 = create an outer rule with a failing condition } again...
   1.142 +        for (var outerRuleCondition2 = 0; outerRuleCondition2 <= 2; outerRuleCondition2++) {
   1.143 +
   1.144 +          // For each of the inner rule types...
   1.145 +          for (var innerRule = 0; innerRule < innerRuleInfo.length; innerRule++) {
   1.146 +
   1.147 +            // Clear rules
   1.148 +            var object = style.sheet;
   1.149 +            while (object.cssRules.length) {
   1.150 +              object.deleteRule(0);
   1.151 +            }
   1.152 +
   1.153 +            // We'll record whether the inner rule should have been applied,
   1.154 +            // according to whether we put passing or failing conditional
   1.155 +            // grouping rules around it.
   1.156 +            var applied = true;
   1.157 +
   1.158 +            if (outerRuleCondition1) {
   1.159 +              // Create an outer conditional rule.
   1.160 +              object.insertRule([outerRuleInfo[outerRule1][0],
   1.161 +                                 outerRuleInfo[outerRule1][outerRuleCondition1],
   1.162 +                                 "{}"].join(" "), 0);
   1.163 +              object = object.cssRules[0];
   1.164 +
   1.165 +              if (outerRuleCondition1 == 2) {
   1.166 +                // If we used a failing condition, we don't expect the inner
   1.167 +                // rule to be applied.
   1.168 +                applied = false;
   1.169 +              }
   1.170 +            }
   1.171 +
   1.172 +            if (outerRuleCondition2) {
   1.173 +              // Create another outer conditional rule as a child of the first
   1.174 +              // outer conditional rule (or the style sheet, if we didn't create
   1.175 +              // a first outer conditional rule).
   1.176 +              object.insertRule([outerRuleInfo[outerRule2][0],
   1.177 +                                 outerRuleInfo[outerRule2][outerRuleCondition2],
   1.178 +                                 "{}"].join(" "), 0);
   1.179 +              object = object.cssRules[0];
   1.180 +
   1.181 +              if (outerRuleCondition2 == 2) {
   1.182 +                // If we used a failing condition, we don't expect the inner
   1.183 +                // rule to be applied.
   1.184 +                applied = false;
   1.185 +              }
   1.186 +            }
   1.187 +
   1.188 +            var outer = object instanceof CSSRule ? object.cssText : "style sheet";
   1.189 +            var inner = innerRuleInfo[innerRule][0];
   1.190 +
   1.191 +            // Insert the inner rule.
   1.192 +            var exception = null;
   1.193 +            try {
   1.194 +              object.insertRule(inner, 0);
   1.195 +            } catch (e) {
   1.196 +              exception = e;
   1.197 +            }
   1.198 +
   1.199 +            ok(innerRuleInfo[innerRule][1](applied, object, exception),
   1.200 +               "<" + [outerRule1, outerRuleCondition1, outerRule2,
   1.201 +                      outerRuleCondition2, innerRule].join(",") + "> " +
   1.202 +               "inserting " + inner + " into " + outer.replace(/ *\n */g, ' '));
   1.203 +          }
   1.204 +        }
   1.205 +      }
   1.206 +    }
   1.207 +  }
   1.208 +
   1.209 +  SimpleTest.finish();
   1.210 +}
   1.211 +
   1.212 +SimpleTest.waitForExplicitFinish();
   1.213 +SpecialPowers.pushPrefEnv({ "set": [["layout.css.supports-rule.enabled", true]] }, runTest);
   1.214 +
   1.215 +</script>
   1.216 +</body>
   1.217 +</html>

mercurial