Bug 1035091: Disable @-moz-document on author sheets on nightly and early beta. r?xidorn draft
authorEmilio Cobos Álvarez <emilio@crisal.io>
Wed, 29 Nov 2017 22:16:46 +0100
changeset 705703 2500a44df6f4803238d3696d2c4c348b1aed8e35
parent 705612 ba04a5b6dcb911fac87c23ef18b6a2f0334c8287
child 706228 c6e090cc9090ededa1d2c2dbbc0f85d51e728615
push id91552
push userbmo:emilio@crisal.io
push dateThu, 30 Nov 2017 15:13:05 +0000
reviewersxidorn
bugs1035091
milestone59.0a1
Bug 1035091: Disable @-moz-document on author sheets on nightly and early beta. r?xidorn MozReview-Commit-ID: AAUs1jJifjS
editor/libeditor/tests/test_bug520189.html
layout/reftests/bugs/1035091-2.html
layout/reftests/bugs/1035091-ref.html
layout/reftests/bugs/1035091.html
layout/reftests/bugs/reftest.list
layout/reftests/scoped-style/reftest.list
layout/reftests/stylesheet-cloning/reftest.list
layout/reftests/w3c-css/submitted/conditional3/reftest.list
layout/style/StylePrefs.cpp
layout/style/StylePrefs.h
layout/style/nsCSSParser.cpp
layout/style/test/test_bug511909.html
layout/style/test/test_condition_text.html
layout/style/test/test_css_eof_handling.html
layout/style/test/test_rule_insertion.html
layout/style/test/test_rule_serialization.html
modules/libpref/init/all.js
--- a/editor/libeditor/tests/test_bug520189.html
+++ b/editor/libeditor/tests/test_bug520189.html
@@ -608,14 +608,18 @@ function runTest(test) {
     is(iframes.length, expectedIFrameCount, "Only " + expectedIFrameCount + " iframe should be pasted");
     if (expectedIFrameCount > 0) {
       ok(!iframes[0].hasAttribute("src"), "iframe should not have a src attrib");
     }
   }
 }
 
 SimpleTest.waitForExplicitFinish();
-addLoadEvent(doNextTest);
 
+addLoadEvent(function() {
+  SpecialPowers.pushPrefEnv(
+    { "set": [["layout.css.moz-document.content.enabled", true]]},
+    doNextTest)
+});
 </script>
 </pre>
 </body>
 </html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/1035091-2.html
@@ -0,0 +1,8 @@
+<!doctype html>
+<style>
+div { color: green; }
+@-moz-document url-prefix() {
+  div { color: red; }
+}
+</style>
+<div>Should be green</div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/1035091-ref.html
@@ -0,0 +1,2 @@
+<!doctype html>
+<div style="color: green;">Should be green</div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/1035091.html
@@ -0,0 +1,7 @@
+<!doctype html>
+<style>
+@-moz-document url-prefix() {
+  div { color: green; }
+}
+</style>
+<div>Should be green</div>
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -2044,8 +2044,10 @@ needs-focus != 1377447-1.html 1377447-2.
 == 1401992.html 1401992-ref.html
 == 1405878-1.xml 1405878-1-ref.xml
 == 1404057.html 1404057-ref.html
 != 1404057.html 1404057-noref.html
 == 1406183-1.html 1406183-1-ref.html
 == 1410028.html 1410028-ref.html
 test-pref(font.size.systemFontScale,200) == 1412743.html 1412743-ref.html
 == 1419820-1.html 1419820-1-ref.html
+pref(layout.css.moz-document.content.enabled,true) == 1035091.html 1035091-ref.html
+pref(layout.css.moz-document.content.enabled,false) == 1035091-2.html 1035091-ref.html
--- a/layout/reftests/scoped-style/reftest.list
+++ b/layout/reftests/scoped-style/reftest.list
@@ -45,15 +45,15 @@ fails-if(styloVsGecko||stylo) == scoped-
 asserts-if(styloVsGecko,0-1) asserts-if(stylo,1) == scoped-style-dynamic-012.svg scoped-style-dynamic-012-ref.svg # bug 1394603: 0-1 styloVsGecko asserts because there are 0 Gecko asserts and 1 Stylo assert.
 fails-if(styloVsGecko) asserts-if(styloVsGecko,1) asserts-if(stylo,1) fails-if(stylo) == scoped-style-dynamic-013.svg scoped-style-dynamic-013-ref.svg # bug 1394603: 0-1 styloVsGecko asserts because there are 0 Gecko asserts and 1 Stylo assert.
 asserts-if(styloVsGecko,0-1) asserts-if(stylo,1) == scoped-style-dynamic-014.svg scoped-style-dynamic-014-ref.svg # bug 1394603: 0-1 styloVsGecko asserts because there are 0 Gecko asserts and 1 Stylo assert.
 fails-if(styloVsGecko) asserts-if(styloVsGecko,0-1) asserts-if(stylo,1) fails-if(stylo) == scoped-style-dynamic-015.svg scoped-style-dynamic-015-ref.svg # bug 1394603: 0-1 styloVsGecko asserts because there are 0 Gecko asserts and 1 Stylo assert.
 fails-if(styloVsGecko||stylo) == scoped-style-import.html scoped-style-import-ref.html
 fails-if(styloVsGecko||stylo) == scoped-style-media.html scoped-style-media-ref.html
 fails-if(styloVsGecko||stylo) == scoped-style-namespace.html scoped-style-namespace-ref.html
 fails-if(styloVsGecko||stylo) == scoped-style-charset.html scoped-style-charset-ref.html
-fails-if(styloVsGecko||stylo) == scoped-style-document.html scoped-style-document-ref.html
+pref(layout.css.moz-document.content.enabled,true) fails-if(styloVsGecko||stylo) == scoped-style-document.html scoped-style-document-ref.html
 fails-if(styloVsGecko||stylo) == scoped-style-font-face.html scoped-style-font-face-ref.html
 fails-if(styloVsGecko||stylo) == scoped-style-keyframes.html scoped-style-keyframes-ref.html
 fails-if(styloVsGecko||stylo) == scoped-style-supports.html scoped-style-supports-ref.html
 pref(layout.css.scope-pseudo.enabled,true) fails-if(styloVsGecko||stylo) == scoped-style-pseudo-001.html scoped-style-pseudo-001-ref.html
 pref(layout.css.scope-pseudo.enabled,true) fails-if(styloVsGecko||stylo) == scoped-style-pseudo-002.html scoped-style-pseudo-002-ref.html
 pref(layout.css.scope-pseudo.enabled,true) == scoped-style-pseudo-003.html scoped-style-pseudo-003-ref.html
--- a/layout/reftests/stylesheet-cloning/reftest.list
+++ b/layout/reftests/stylesheet-cloning/reftest.list
@@ -1,7 +1,7 @@
 == counter-style-rule-clone.html glyphs-ref.html # passes trivially
 # because "Dynamic change on @counter-style not yet supported"
-== document-rule-clone.html shouldbegreen-ref.html
+pref(layout.css.moz-document.content.enabled,true) == document-rule-clone.html shouldbegreen-ref.html
 == media-rule-clone.html shouldbegreen-ref.html
 == insert-after-clone.html shouldbegreen-ref.html
 == style-rule-clone.html shouldbegreen-ref.html
 == supports-rule-clone.html shouldbegreen-ref.html
--- a/layout/reftests/w3c-css/submitted/conditional3/reftest.list
+++ b/layout/reftests/w3c-css/submitted/conditional3/reftest.list
@@ -19,18 +19,18 @@
 == css-supports-019.xht support/pass.xht
 == css-supports-020.xht support/pass.xht
 == css-supports-021.xht support/pass.xht
 == css-supports-022.xht support/pass.xht
 == css-supports-023.xht support/pass.xht
 == css-supports-024.xht support/pass.xht
 == css-supports-025.xht support/pass.xht
 == css-supports-026.xht support/pass.xht
-== css-supports-027.xht support/pass.xht
-== css-supports-028.xht support/pass.xht
+pref(layout.css.moz-document.content.enabled,true) == css-supports-027.xht support/pass.xht
+pref(layout.css.moz-document.content.enabled,true) == css-supports-028.xht support/pass.xht
 == css-supports-029.xht support/pass.xht
 == css-supports-030.xht support/pass.xht
 == css-supports-031.xht support/pass.xht
 == css-supports-032.xht support/pass.xht
 == css-supports-033.xht support/pass.xht
 == css-supports-034.xht support/pass.xht
 == css-supports-035.xht support/pass.xht
 == css-supports-036.xht support/pass.xht
--- a/layout/style/StylePrefs.cpp
+++ b/layout/style/StylePrefs.cpp
@@ -14,16 +14,17 @@ bool StylePrefs::sFontDisplayEnabled;
 bool StylePrefs::sOpentypeSVGEnabled;
 bool StylePrefs::sWebkitPrefixedAliasesEnabled;
 bool StylePrefs::sWebkitDevicePixelRatioEnabled;
 bool StylePrefs::sMozGradientsEnabled;
 bool StylePrefs::sControlCharVisibility;
 bool StylePrefs::sFramesTimingFunctionEnabled;
 bool StylePrefs::sUnprefixedFullscreenApiEnabled;
 bool StylePrefs::sVisitedLinksEnabled;
+bool StylePrefs::sMozDocumentEnabledInContent;
 
 /* static */ void
 StylePrefs::Init()
 {
   Preferences::AddBoolVarCache(&sFontDisplayEnabled,
                                "layout.css.font-display.enabled");
   Preferences::AddBoolVarCache(&sOpentypeSVGEnabled,
                                "gfx.font_rendering.opentype_svg.enabled");
@@ -36,11 +37,13 @@ StylePrefs::Init()
   Preferences::AddBoolVarCache(&sControlCharVisibility,
                                "layout.css.control-characters.visible");
   Preferences::AddBoolVarCache(&sFramesTimingFunctionEnabled,
                                "layout.css.frames-timing.enabled");
   Preferences::AddBoolVarCache(&sUnprefixedFullscreenApiEnabled,
                                "full-screen-api.unprefix.enabled");
   Preferences::AddBoolVarCache(&sVisitedLinksEnabled,
                                "layout.css.visited_links_enabled");
+  Preferences::AddBoolVarCache(&sMozDocumentEnabledInContent,
+                               "layout.css.moz-document.content.enabled");
 }
 
 } // namespace mozilla
--- a/layout/style/StylePrefs.h
+++ b/layout/style/StylePrefs.h
@@ -17,15 +17,16 @@ struct StylePrefs
   static bool sOpentypeSVGEnabled;
   static bool sWebkitPrefixedAliasesEnabled;
   static bool sWebkitDevicePixelRatioEnabled;
   static bool sMozGradientsEnabled;
   static bool sControlCharVisibility;
   static bool sFramesTimingFunctionEnabled;
   static bool sUnprefixedFullscreenApiEnabled;
   static bool sVisitedLinksEnabled;
+  static bool sMozDocumentEnabledInContent;
 
   static void Init();
 };
 
 } // namespace mozilla
 
 #endif // mozilla_StylePrefs_h
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -3766,16 +3766,21 @@ CSSParserImpl::ParseMediaRule(RuleAppend
 }
 
 // Parse a @-moz-document rule.  This is like an @media rule, but instead
 // of a medium it has a nonempty list of items where each item is either
 // url(), url-prefix(), or domain().
 bool
 CSSParserImpl::ParseMozDocumentRule(RuleAppendFunc aAppendFunc, void* aData)
 {
+  if (mParsingMode == css::eAuthorSheetFeatures &&
+      !StylePrefs::sMozDocumentEnabledInContent) {
+    return false;
+  }
+
   css::DocumentRule::URL *urls = nullptr;
   css::DocumentRule::URL **next = &urls;
 
   uint32_t linenum, colnum;
   if (!GetNextTokenLocation(true, &linenum, &colnum)) {
     return false;
   }
 
--- a/layout/style/test/test_bug511909.html
+++ b/layout/style/test/test_bug511909.html
@@ -9,150 +9,143 @@
 
 <style type="text/css">
 a {
     font-weight: bold; 
 }
   #pink {
     color: pink;
   }
-  
+
   #green {
     color: green;
   }
-  
+
   #blue {
     color: blue;
   }
 
-
 pre {
    border: 1px solid black;
 }
 </style>
-  
+
 <style type="text/css">
 @-moz-document regexp(".*test_bug511909.*"){
     #d {
       color: pink;
     }
 }
+</style>
 
-</style>
-  
 <style type="text/css">
-    
 @media screen {
    #m {
       color: green;
    }
 }
+</style>
 
-</style>
-  
 <style type="text/css">
-  
 @-moz-document regexp(".*test_bug511909.*"){
   @media screen {
       #dm {
          color: blue;
       }
    }
 }
+</style>
 
-</style>
-  
 <!-- should parse -->
 <style type="text/css">
-
 @media print {
   @-moz-document regexp("not_this_url"),}
     #mx {
         color: pink;
     }
   }
 }
+</style>
 
-</style>
-  
 <!-- should parse -->
 <style type="text/css">
-    
 @-moz-document regexp("not_this_url"){
   @media print ,}
     #mxx {
       color: blue;
     }
   }
 }
+</style>
 
-</style>
-  
-<style type="text/css">  
-  
+<style type="text/css">
 @media screen {
   @-moz-document regexp(".*test_bug511909.*"){
       #md {
          color: green;
       }
    }
 }
+</style>
 
-</style>
-  
 <style type="text/css">
-    
 @media screen {
   @-moz-document regexp(".*test_bug511909.*"){
       @media screen { 
         @-moz-document regexp(".*test_bug511909.*"){
           @media screen {
             #me {
              color: blue; 
             }
           }
         }
      }
    }
 }
-  
 </style>
 </head>
 <body>
   <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=511909">Mozilla Bug 511909</a>
   <p id="display"></p>
   <div id="content" style="display: none">
-    
   </div>
-  
+
   <script class="testbody" type="text/javascript">
+    SimpleTest.waitForExplicitFinish();
 
-    SimpleTest.waitForExplicitFinish();
-    
     addLoadEvent(function() {
-    var pink = getComputedStyle(document.getElementById("pink"), "");
-    var green = getComputedStyle(document.getElementById("green"), "");
-    var blue = getComputedStyle(document.getElementById("blue"), "");
-                 
-    var cs1 = getComputedStyle(document.getElementById("d"), "");
-    var cs2 = getComputedStyle(document.getElementById("m"), "");
-    var cs3 = getComputedStyle(document.getElementById("dm"), "");
-    var cs4 = getComputedStyle(document.getElementById("md"), "");
-    var cs5 = getComputedStyle(document.getElementById("mx"), "");                 
-    var cs6 = getComputedStyle(document.getElementById("mxx"), "");                  
-    var cs7 = getComputedStyle(document.getElementById("me"), "");  
-                 
-    is(cs1.color, pink.color, "@-moz-document applies");
-    is(cs2.color, green.color, "@media applies");
-    is(cs3.color, blue.color, "@media nested in @-moz-document applies");
-    is(cs4.color, green.color, "@-moz-document nested in @media applies");
-    is(cs5.color, pink.color, "broken @media nested in @-moz-document correctly handled");      
-    is(cs6.color, blue.color, "broken @-moz-document nested in @media correctly handled");   
-    is(cs7.color, blue.color, "@media nested in @-moz-document nested in @media applies");
-    SimpleTest.finish();
+      SpecialPowers.pushPrefEnv(
+        { "set": [["layout.css.moz-document.content.enabled", true ]]},
+        function() {
+          // Ensure all the sheets are re-parsed, so that the pref applies.
+          for (const sheet of Array.from(document.querySelectorAll('style'))) {
+            sheet.textContent += "/* dummy */";
+          }
+
+          var pink = getComputedStyle(document.getElementById("pink"), "");
+          var green = getComputedStyle(document.getElementById("green"), "");
+          var blue = getComputedStyle(document.getElementById("blue"), "");
+
+          var cs1 = getComputedStyle(document.getElementById("d"), "");
+          var cs2 = getComputedStyle(document.getElementById("m"), "");
+          var cs3 = getComputedStyle(document.getElementById("dm"), "");
+          var cs4 = getComputedStyle(document.getElementById("md"), "");
+          var cs5 = getComputedStyle(document.getElementById("mx"), "");
+          var cs6 = getComputedStyle(document.getElementById("mxx"), "");
+          var cs7 = getComputedStyle(document.getElementById("me"), "");
+
+          is(cs1.color, pink.color, "@-moz-document applies");
+          is(cs2.color, green.color, "@media applies");
+          is(cs3.color, blue.color, "@media nested in @-moz-document applies");
+          is(cs4.color, green.color, "@-moz-document nested in @media applies");
+          is(cs5.color, pink.color, "broken @media nested in @-moz-document correctly handled");
+          is(cs6.color, blue.color, "broken @-moz-document nested in @media correctly handled");
+          is(cs7.color, blue.color, "@media nested in @-moz-document nested in @media applies");
+          SimpleTest.finish();
+        })
     });
   </script>
 <div>
 <pre>default style
 </pre>
 <a id="pink">This line should be pink</a><br>
   
 <a id="green">This line should be green</a><br>
--- a/layout/style/test/test_condition_text.html
+++ b/layout/style/test/test_condition_text.html
@@ -81,13 +81,15 @@ function runTest()
       is(rule.conditionText, rule.media.mediaText, "rule " + i + " conditionText matches media.mediaText");
     }
   }
 
   SimpleTest.finish();
 }
 
 SimpleTest.waitForExplicitFinish();
-runTest();
+SpecialPowers.pushPrefEnv(
+  { "set": [["layout.css.moz-document.content.enabled", true]]},
+  runTest);
 </script>
 </pre>
 </body>
 </html>
--- a/layout/style/test/test_css_eof_handling.html
+++ b/layout/style/test/test_css_eof_handling.html
@@ -83,17 +83,17 @@ const tests = [
            "iVBORw0KGgoAAAANSUhEUgAAAAQAAAAEAQAAAACBiqPTAAAAEElEQVQI12N4" +
            "wHCBYQNDAQAMuALRrGb97AAAAABJRU5ErkJggg==') }",
       tst: "#t { background-image: url('data:image/png;base64," +
            "iVBORw0KGgoAAAANSUhEUgAAAAQAAAAEAQAAAACBiqPTAAAAEElEQVQI12N4" +
            "wHCBYQNDAQAMuALRrGb97AAAAABJRU5ErkJggg=='",
       prop: "background-image", pseudo: ""
   },
   {
-      name: "url-token 4",	/*Bug 751939*/
+      name: "url-token 4",  /*Bug 751939*/
       ref: "#r { background-image: url( )}",
       tst: "#t { background-image: url(" ,
       prop: "background-image", pseudo: ""
   },
   {
       name: "counter",
       ref: "#r::before { content: counter(tr, upper-alpha) }",
       tst: "#t::before { content: counter(tr, upper-alpha",
@@ -191,88 +191,93 @@ const tests = [
   {
       name: "@-moz-document 2",
       ref: "@-moz-document domain('example.com') { p {} }",
       tst: "@-moz-document domain('example.com') { p {"
   }
 ];
 
 const basestyle = ("table {\n"+
-		   "    border-collapse: collapse;\n"+
-		   "}\n"+
-		   "td {\n"+
-		   "    width: 1.5em;\n"+
-		   "    height: 1.5em;\n"+
-		   "    border: 1px solid black;\n"+
-		   "    text-align: center;\n"+
-		   "    margin: 0;\n"+
-		   "}\n"+
-		   "tr { counter-increment: tr }\n");
+       "    border-collapse: collapse;\n"+
+       "}\n"+
+       "td {\n"+
+       "    width: 1.5em;\n"+
+       "    height: 1.5em;\n"+
+       "    border: 1px solid black;\n"+
+       "    text-align: center;\n"+
+       "    margin: 0;\n"+
+       "}\n"+
+       "tr { counter-increment: tr }\n");
 
 /* This is more complicated than it might look like it needs to be,
    because for each subtest we have to splat stuff into the iframe,
    allow the renderer to run, and only then interrogate the computed
    styles.  */
 
 SimpleTest.waitForExplicitFinish();
- 
+
 window.onload = function() {
-    const frame = document.getElementById("display");
-    var curTest = 0;
+  SpecialPowers.pushPrefEnv(
+    { "set": [["layout.css.moz-document.content.enabled", true]]},
+    function() {
+      const frame = document.getElementById("display");
+      var curTest = 0;
 
-    const prepareTest = function() {
-	var cd = frame.contentDocument;
-	cd.open();
-	cd.write('<!DOCTYPE HTML><html><head>' +
-		 '<style>\n' + basestyle + '</style>\n' +
-		 '<style>\n' + tests[curTest].ref + '</style>\n' +
-		 '<style>\n' + tests[curTest].tst + '</style>\n' +
-		 '</head><body>\n' +
-		 '<table><tr><td id="r"><td id="t"></table>' +
-		 '</body></html>');
-	cd.close();
-    };
+      const prepareTest = function() {
+        var cd = frame.contentDocument;
+        cd.open();
+        cd.write('<!DOCTYPE HTML><html><head>' +
+          '<style>\n' + basestyle + '</style>\n' +
+          '<style>\n' + tests[curTest].ref + '</style>\n' +
+          '<style>\n' + tests[curTest].tst + '</style>\n' +
+          '</head><body>\n' +
+          '<table><tr><td id="r"><td id="t"></table>' +
+          '</body></html>');
+        cd.close();
+      };
 
-    const checkTest = function() {
-	var cd = frame.contentDocument;
-	var _is = tests[curTest].todo ? todo_is : is;
-	var _ok = tests[curTest].todo ? todo : ok;
+      const checkTest = function() {
+        var cd = frame.contentDocument;
+        var _is = tests[curTest].todo ? todo_is : is;
+        var _ok = tests[curTest].todo ? todo : ok;
 
-	if (cd.styleSheets[1].cssRules.length == 1 &&
-	    cd.styleSheets[2].cssRules.length == 1) {
-	    // If we have a .prop for this test, the .cssText of the reference
-	    // and test rules will differ in the selector.  Change #t to #r
-	    // in the test rule.
-	    var ref_canon = cd.styleSheets[1].cssRules[0].cssText;
-	    var tst_canon = cd.styleSheets[2].cssRules[0].cssText;
-	    tst_canon = tst_canon.replace(/(#|%23)t\b/, "$1r");
-	    _is(tst_canon, ref_canon,
-		tests[curTest].name + " (canonicalized rule)");
-	} else {
-	    _ok(false, tests[curTest].name + " (rule missing)");
-	}
-	if (tests[curTest].prop) {
-	    var prop = tests[curTest].prop;
-	    var pseudo = tests[curTest].pseudo;
+        if (cd.styleSheets[1].cssRules.length == 1 &&
+          cd.styleSheets[2].cssRules.length == 1) {
+          // If we have a .prop for this test, the .cssText of the reference
+          // and test rules will differ in the selector.  Change #t to #r
+          // in the test rule.
+          var ref_canon = cd.styleSheets[1].cssRules[0].cssText;
+          var tst_canon = cd.styleSheets[2].cssRules[0].cssText;
+          tst_canon = tst_canon.replace(/(#|%23)t\b/, "$1r");
+          _is(tst_canon, ref_canon,
+              tests[curTest].name + " (canonicalized rule)");
+        } else {
+          _ok(false, tests[curTest].name + " (rule missing)");
+        }
+        if (tests[curTest].prop) {
+          var prop = tests[curTest].prop;
+          var pseudo = tests[curTest].pseudo;
 
-	    var refElt = cd.getElementById("r");
-	    var tstElt = cd.getElementById("t");
-	    var refStyle = cd.defaultView.getComputedStyle(refElt, pseudo);
-	    var tstStyle = cd.defaultView.getComputedStyle(tstElt, pseudo);
-	    _is(tstStyle.getPropertyValue(prop),
-                refStyle.getPropertyValue(prop),
-                tests[curTest].name + " (computed style)");
-	}
-	curTest++;
-	if (curTest < tests.length) {
-	    prepareTest();
-	} else {
-	    SimpleTest.finish();
-	}
-    };
+          var refElt = cd.getElementById("r");
+          var tstElt = cd.getElementById("t");
+          var refStyle = cd.defaultView.getComputedStyle(refElt, pseudo);
+          var tstStyle = cd.defaultView.getComputedStyle(tstElt, pseudo);
+          _is(tstStyle.getPropertyValue(prop),
+              refStyle.getPropertyValue(prop),
+              tests[curTest].name + " (computed style)");
+        }
+        curTest++;
+        if (curTest < tests.length) {
+          prepareTest();
+        } else {
+          SimpleTest.finish();
+        }
+      };
 
-    frame.onload = function(){setTimeout(checkTest, 0);};
-    prepareTest();
+      frame.onload = function(){setTimeout(checkTest, 0);};
+      prepareTest();
+    }
+  )
 };
 </script>
 </pre>
 </body>
 </html>
--- a/layout/style/test/test_rule_insertion.html
+++ b/layout/style/test/test_rule_insertion.html
@@ -229,12 +229,16 @@ function runTest()
       }
     }
   }
 
   SimpleTest.finish();
 }
 
 SimpleTest.waitForExplicitFinish();
-runTest();
+
+SpecialPowers.pushPrefEnv(
+  { "set": [["layout.css.moz-document.content.enabled", true ]]},
+  runTest,
+);
 </script>
 </body>
 </html>
--- a/layout/style/test/test_rule_serialization.html
+++ b/layout/style/test/test_rule_serialization.html
@@ -20,34 +20,44 @@ var rules = [
   { rule: "@-moz-document url-prefix('http://www.example.com/') {}" },
   { rule: '@-moz-document url-prefix("http://www.example.com/") {}' },
   { rule: "@-moz-document domain('example.com') {}" },
   { rule: '@-moz-document domain("example.com") {}' },
   { rule: "@-moz-document regexp('http://www.w3.org/TR/\\d{4}/[^/]*-CSS2-\\d{8}/') {}" },
   { rule: '@-moz-document regexp("http://www.w3.org/TR/\\d{4}/[^/]*-CSS2-\\d{8}/") {}' },
 ];
 
-var style = document.getElementById("style");
-var style_text = document.createTextNode("");
-style.appendChild(style_text);
+SimpleTest.waitForExplicitFinish();
 
-for (var i in rules) {
-  var obj = rules[i];
-  var rule = obj.rule;
+SpecialPowers.pushPrefEnv(
+  { "set": [["layout.css.moz-document.content.enabled", true ]]},
+  function() {
+    var style = document.getElementById("style");
+    var style_text = document.createTextNode("");
+    style.appendChild(style_text);
+
+    for (var i in rules) {
+      var obj = rules[i];
+      var rule = obj.rule;
 
-  style_text.data = rule;
-  is(style.sheet.cssRules.length, 1, "should have one rule");
-  var ser1 = style.sheet.cssRules[0].cssText;
-  if ("is_canonical" in obj) {
-    is(ser1, rule, "rule '" + rule + "' should serialize to itself");
-  }
+      style_text.data = rule;
+      is(style.sheet.cssRules.length, 1, "should have one rule");
+      var ser1 = style.sheet.cssRules[0].cssText;
+      if ("is_canonical" in obj) {
+        is(ser1, rule, "rule '" + rule + "' should serialize to itself");
+      }
 
-  style_text.data = ser1;
-  is(style.sheet.cssRules.length, 1, "should have one rule");
-  var ser2 = style.sheet.cssRules[0].cssText;
-  is(ser2, ser1,
-     "parse+serialize for rule '" + rule + "' should be idempotent");
-}
+      style_text.data = ser1;
+      is(style.sheet.cssRules.length, 1, "should have one rule");
+      var ser2 = style.sheet.cssRules[0].cssText;
+      is(ser2, ser1,
+         "parse+serialize for rule '" + rule + "' should be idempotent");
+    }
+
+    SimpleTest.finish();
+  }
+)
+
 
 </script>
 </pre>
 </body>
 </html>
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -2830,16 +2830,23 @@ pref("layout.word_select.stop_at_punctua
 pref("layout.selection.caret_style", 0);
 
 // pref to report CSS errors to the error console
 pref("layout.css.report_errors", true);
 
 // Should the :visited selector ever match (otherwise :link matches instead)?
 pref("layout.css.visited_links_enabled", true);
 
+// Pref to control whether @-moz-document rules are enabled in content pages.
+#ifdef EARLY_BETA_OR_EARLIER
+pref("layout.css.moz-document.content.enabled",  false);
+#else
+pref("layout.css.moz-document.content.enabled",  true);
+#endif
+
 // Override DPI. A value of -1 means use the maximum of 96 and the system DPI.
 // A value of 0 means use the system DPI. A positive value is used as the DPI.
 // This sets the physical size of a device pixel and thus controls the
 // interpretation of physical units such as "pt".
 pref("layout.css.dpi", -1);
 
 // Set the number of device pixels per CSS pixel. A value <= 0 means choose
 // automatically based on user settings for the platform (e.g., "UI scale factor"