layout/style/test/test_rule_insertion.html

Wed, 31 Dec 2014 13:27:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 13:27:57 +0100
branch
TOR_BUG_3246
changeset 6
8bccb770b82d
permissions
-rw-r--r--

Ignore runtime configuration files generated during quality assurance.

     1 <!DOCTYPE HTML>
     2 <html>
     3 <!--
     4 https://bugzilla.mozilla.org/show_bug.cgi?id=816720
     5 -->
     6 <head>
     7   <title>Test for Bug 816720</title>
     8   <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
     9   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
    10   <style type="text/css" id="style"></style>
    11 </head>
    12 <body>
    14 <pre id="test"></pre>
    16 <p><span id=control-serif>........</span></p>
    17 <p><span id=control-monospace>........</span></p>
    18 <p><span id=test-font>........</span></p>
    20 <style id=other-styles>
    21   #test { font-size: 16px; animation: test 1s both }
    22   #control-serif { font: 16px serif }
    23   #test-font { font: 16px UnlikelyFontName, serif }
    24 </style>
    26 <script type="application/javascript">
    28 // Monospace fonts available on all the platforms we're testing on.
    29 //
    30 // XXX Once bug 817220 is fixed we could instead use the value of
    31 // font.name.monospace.x-western as the monospace font to use.
    32 var MONOSPACE_FONTS = [
    33   "Courier",
    34   "Courier New",
    35   "Monaco",
    36   "DejaVu Sans Mono",
    37   "Droid Sans Mono"
    38 ];
    40 var test = document.getElementById("test");
    41 var controlSerif = document.getElementById("control-serif");
    42 var controlMonospace = document.getElementById("control-monospace");
    43 var testFont = document.getElementById("test-font");
    44 var otherStyles = document.getElementById("other-styles");
    46 otherStyles.sheet.insertRule("#control-monospace { font: 16px " +
    47                              MONOSPACE_FONTS + ", serif }", 0);
    49 var monospaceWidth = controlMonospace.getBoundingClientRect().width;
    50 var serifWidth = controlSerif.getBoundingClientRect().width;
    52 // [at-rule type, passing condition, failing condition]
    53 var outerRuleInfo = [
    54   ["@media", "all", "not all"],
    55   ["@-moz-document", "url-prefix('')", "url-prefix('zzz')"],
    56   ["@supports", "(color: green)", "(unknown: unknown)"]
    57 ];
    59 // [rule, function to test whether the rule was successfully inserted and applied]
    60 var innerRuleInfo = [
    61   ["#test { text-decoration: underline; }",
    62    function(aApplied, aParent, aException) {
    63      return !aException &&
    64             window.getComputedStyle(test, "").textDecoration ==
    65                (aApplied ? "underline" : "none");
    66    }],
    67   ["@page { margin: 4cm; }",
    68    function(aApplied, aParent, aException) {
    69      // just test whether it threw
    70      return !aException;
    71    }],
    72   ["@keyframes test { from { font-size: 100px; } to { font-size: 100px; } }",
    73    function(aApplied, aParent, aException) {
    74      return !aException &&
    75             window.getComputedStyle(test, "").fontSize ==
    76                 (aApplied ? "100px" : "16px")
    77    }],
    78   ["@font-face { font-family: UnlikelyFontName; src: " +
    79      MONOSPACE_FONTS.map(function(s) { return "local('" + s + "')" }).join(", ") + "; }",
    80    function(aApplied, aParent, aException) {
    81      var width = testFont.getBoundingClientRect().width;
    82      if (aException) {
    83        return false;
    84      }
    85      if (navigator.oscpu.match(/Linux/) ||
    86          navigator.oscpu.match(/Android/) ||
    87          SpecialPowers.Services.appinfo.name == "B2G") {
    88        return true;
    89     }
    90     return Math.abs(width - (aApplied ? monospaceWidth : serifWidth)) <= 1; // bug 769194 prevents local()
    91                                              // fonts working on Android
    92    }],
    93   ["@charset 'UTF-8';",
    94    function(aApplied, aParent, aException) {
    95      // just test whether it threw
    96      return aParent instanceof CSSRule ? aException : !aException;
    97    }],
    98   ["@import url(nothing.css);",
    99    function(aApplied, aParent, aException) {
   100      // just test whether it threw
   101      return aParent instanceof CSSRule ? aException : !aException;
   102    }],
   103   ["@namespace test url(http://example.org);",
   104    function(aApplied, aParent, aException) {
   105      // just test whether it threw
   106      return aParent instanceof CSSRule ? aException : !aException;
   107    }],
   108 ];
   110 function runTest()
   111 {
   112   // First, assert that our assumed available fonts are indeed available
   113   // and have expected metrics.
   114   ok(monospaceWidth > 0, "monospace text has width");
   115   ok(serifWidth > 0, "serif text has width");
   116   ok(Math.abs(monospaceWidth - serifWidth) > 1, "monospace and serif text have sufficiently different widths");
   118   // And that the #test-font element starts off using the "serif" font.
   119   var initialFontTestWidth = testFont.getBoundingClientRect().width;
   120   is(initialFontTestWidth, serifWidth);
   122   // We construct a style sheet with zero, one or two levels of conditional
   123   // grouping rules (taken from outerRuleInfo), with one of the inner rules
   124   // at the deepest level.
   125   var style = document.getElementById("style");
   127   // For each of the outer rule types...
   128   for (var outerRule1 = 0; outerRule1 < outerRuleInfo.length; outerRule1++) {
   129     // For each of { 0 = don't create an outer rule,
   130     //               1 = create an outer rule with a passing condition,
   131     //               2 = create an outer rule with a failing condition }...
   132     for (var outerRuleCondition1 = 0; outerRuleCondition1 <= 2; outerRuleCondition1++) {
   134       // For each of the outer rule types again...
   135       for (var outerRule2 = 0; outerRule2 < outerRuleInfo.length; outerRule2++) {
   136         // For each of { 0 = don't create an outer rule,
   137         //               1 = create an outer rule with a passing condition,
   138         //               2 = create an outer rule with a failing condition } again...
   139         for (var outerRuleCondition2 = 0; outerRuleCondition2 <= 2; outerRuleCondition2++) {
   141           // For each of the inner rule types...
   142           for (var innerRule = 0; innerRule < innerRuleInfo.length; innerRule++) {
   144             // Clear rules
   145             var object = style.sheet;
   146             while (object.cssRules.length) {
   147               object.deleteRule(0);
   148             }
   150             // We'll record whether the inner rule should have been applied,
   151             // according to whether we put passing or failing conditional
   152             // grouping rules around it.
   153             var applied = true;
   155             if (outerRuleCondition1) {
   156               // Create an outer conditional rule.
   157               object.insertRule([outerRuleInfo[outerRule1][0],
   158                                  outerRuleInfo[outerRule1][outerRuleCondition1],
   159                                  "{}"].join(" "), 0);
   160               object = object.cssRules[0];
   162               if (outerRuleCondition1 == 2) {
   163                 // If we used a failing condition, we don't expect the inner
   164                 // rule to be applied.
   165                 applied = false;
   166               }
   167             }
   169             if (outerRuleCondition2) {
   170               // Create another outer conditional rule as a child of the first
   171               // outer conditional rule (or the style sheet, if we didn't create
   172               // a first outer conditional rule).
   173               object.insertRule([outerRuleInfo[outerRule2][0],
   174                                  outerRuleInfo[outerRule2][outerRuleCondition2],
   175                                  "{}"].join(" "), 0);
   176               object = object.cssRules[0];
   178               if (outerRuleCondition2 == 2) {
   179                 // If we used a failing condition, we don't expect the inner
   180                 // rule to be applied.
   181                 applied = false;
   182               }
   183             }
   185             var outer = object instanceof CSSRule ? object.cssText : "style sheet";
   186             var inner = innerRuleInfo[innerRule][0];
   188             // Insert the inner rule.
   189             var exception = null;
   190             try {
   191               object.insertRule(inner, 0);
   192             } catch (e) {
   193               exception = e;
   194             }
   196             ok(innerRuleInfo[innerRule][1](applied, object, exception),
   197                "<" + [outerRule1, outerRuleCondition1, outerRule2,
   198                       outerRuleCondition2, innerRule].join(",") + "> " +
   199                "inserting " + inner + " into " + outer.replace(/ *\n */g, ' '));
   200           }
   201         }
   202       }
   203     }
   204   }
   206   SimpleTest.finish();
   207 }
   209 SimpleTest.waitForExplicitFinish();
   210 SpecialPowers.pushPrefEnv({ "set": [["layout.css.supports-rule.enabled", true]] }, runTest);
   212 </script>
   213 </body>
   214 </html>

mercurial