layout/style/test/test_rule_insertion.html

Wed, 31 Dec 2014 06:55:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:50 +0100
changeset 2
7e26c7da4463
permissions
-rw-r--r--

Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2

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

mercurial