Bug 1396066: Restrict system-metric media features to UA and chrome sheets only. r?xidorn draft
authorEmilio Cobos Álvarez <emilio@crisal.io>
Mon, 02 Oct 2017 19:40:18 +0200
changeset 675932 77c763f82d33ca1bcdb3f03fdc9d5017eb885cb3
parent 675931 cecb8c3ab1e1a23cac3a2d2c12a51f575d002e02
child 675933 45381639c6bc9651c2fa93df8e9aae778261ed97
push id83306
push userbmo:emilio@crisal.io
push dateFri, 06 Oct 2017 08:13:37 +0000
reviewersxidorn
bugs1396066
milestone58.0a1
Bug 1396066: Restrict system-metric media features to UA and chrome sheets only. r?xidorn MozReview-Commit-ID: 38jRV6mPbE3
layout/style/nsCSSParser.cpp
layout/style/nsMediaFeatures.cpp
layout/style/nsMediaFeatures.h
layout/style/test/chrome/bug418986-2.js
layout/style/test/test_media_queries.html
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -3497,16 +3497,21 @@ CSSParserImpl::ParseMediaQueryExpression
 
   nsMediaExpression *expr = aQuery->NewExpression();
 
   // case insensitive from CSS - must be lower cased
   nsContentUtils::ASCIIToLower(mToken.mIdent);
   nsDependentString featureString(mToken.mIdent, 0);
   uint8_t satisfiedReqFlags = 0;
 
+  if (EnabledState() & (CSSEnabledState::eInUASheets |
+                        CSSEnabledState::eInChrome)) {
+    satisfiedReqFlags |= nsMediaFeature::eUserAgentAndChromeOnly;
+  }
+
   // Strip off "-webkit-" prefix from featureString:
   if (StylePrefs::sWebkitPrefixedAliasesEnabled &&
       StringBeginsWith(featureString, NS_LITERAL_STRING("-webkit-"))) {
     satisfiedReqFlags |= nsMediaFeature::eHasWebkitPrefix;
     featureString.Rebind(featureString, 8);
   }
   if (StylePrefs::sWebkitDevicePixelRatioEnabled) {
     satisfiedReqFlags |= nsMediaFeature::eWebkitDevicePixelRatioPrefEnabled;
--- a/layout/style/nsMediaFeatures.cpp
+++ b/layout/style/nsMediaFeatures.cpp
@@ -632,178 +632,184 @@ nsMediaFeatures::features[] = {
     nsMediaFeature::eNoRequirements,
     { nullptr },
     GetIsResourceDocument
   },
   {
     &nsGkAtoms::_moz_color_picker_available,
     nsMediaFeature::eMinMaxNotAllowed,
     nsMediaFeature::eBoolInteger,
-    nsMediaFeature::eNoRequirements,
+    nsMediaFeature::eUserAgentAndChromeOnly,
     { &nsGkAtoms::color_picker_available },
     GetSystemMetric
   },
   {
     &nsGkAtoms::_moz_scrollbar_start_backward,
     nsMediaFeature::eMinMaxNotAllowed,
     nsMediaFeature::eBoolInteger,
-    nsMediaFeature::eNoRequirements,
+    nsMediaFeature::eUserAgentAndChromeOnly,
     { &nsGkAtoms::scrollbar_start_backward },
     GetSystemMetric
   },
   {
     &nsGkAtoms::_moz_scrollbar_start_forward,
     nsMediaFeature::eMinMaxNotAllowed,
     nsMediaFeature::eBoolInteger,
-    nsMediaFeature::eNoRequirements,
+    nsMediaFeature::eUserAgentAndChromeOnly,
     { &nsGkAtoms::scrollbar_start_forward },
     GetSystemMetric
   },
   {
     &nsGkAtoms::_moz_scrollbar_end_backward,
     nsMediaFeature::eMinMaxNotAllowed,
     nsMediaFeature::eBoolInteger,
-    nsMediaFeature::eNoRequirements,
+    nsMediaFeature::eUserAgentAndChromeOnly,
     { &nsGkAtoms::scrollbar_end_backward },
     GetSystemMetric
   },
   {
     &nsGkAtoms::_moz_scrollbar_end_forward,
     nsMediaFeature::eMinMaxNotAllowed,
     nsMediaFeature::eBoolInteger,
-    nsMediaFeature::eNoRequirements,
+    nsMediaFeature::eUserAgentAndChromeOnly,
     { &nsGkAtoms::scrollbar_end_forward },
     GetSystemMetric
   },
   {
     &nsGkAtoms::_moz_scrollbar_thumb_proportional,
     nsMediaFeature::eMinMaxNotAllowed,
     nsMediaFeature::eBoolInteger,
-    nsMediaFeature::eNoRequirements,
+    nsMediaFeature::eUserAgentAndChromeOnly,
     { &nsGkAtoms::scrollbar_thumb_proportional },
     GetSystemMetric
   },
   {
     &nsGkAtoms::_moz_overlay_scrollbars,
     nsMediaFeature::eMinMaxNotAllowed,
     nsMediaFeature::eBoolInteger,
-    nsMediaFeature::eNoRequirements,
+    nsMediaFeature::eUserAgentAndChromeOnly,
     { &nsGkAtoms::overlay_scrollbars },
     GetSystemMetric
   },
   {
     &nsGkAtoms::_moz_windows_default_theme,
     nsMediaFeature::eMinMaxNotAllowed,
     nsMediaFeature::eBoolInteger,
-    nsMediaFeature::eNoRequirements,
+    nsMediaFeature::eUserAgentAndChromeOnly,
     { &nsGkAtoms::windows_default_theme },
     GetSystemMetric
   },
   {
     &nsGkAtoms::_moz_mac_graphite_theme,
     nsMediaFeature::eMinMaxNotAllowed,
     nsMediaFeature::eBoolInteger,
-    nsMediaFeature::eNoRequirements,
+    nsMediaFeature::eUserAgentAndChromeOnly,
     { &nsGkAtoms::mac_graphite_theme },
     GetSystemMetric
   },
   {
     &nsGkAtoms::_moz_mac_yosemite_theme,
     nsMediaFeature::eMinMaxNotAllowed,
     nsMediaFeature::eBoolInteger,
-    nsMediaFeature::eNoRequirements,
+    nsMediaFeature::eUserAgentAndChromeOnly,
     { &nsGkAtoms::mac_yosemite_theme },
     GetSystemMetric
   },
   {
     &nsGkAtoms::_moz_windows_accent_color_in_titlebar,
     nsMediaFeature::eMinMaxNotAllowed,
     nsMediaFeature::eBoolInteger,
-    nsMediaFeature::eNoRequirements,
+    nsMediaFeature::eUserAgentAndChromeOnly,
     { &nsGkAtoms::windows_accent_color_in_titlebar },
     GetSystemMetric
   },
   {
     &nsGkAtoms::_moz_windows_compositor,
     nsMediaFeature::eMinMaxNotAllowed,
     nsMediaFeature::eBoolInteger,
-    nsMediaFeature::eNoRequirements,
+    nsMediaFeature::eUserAgentAndChromeOnly,
     { &nsGkAtoms::windows_compositor },
     GetSystemMetric
   },
   {
     &nsGkAtoms::_moz_windows_classic,
     nsMediaFeature::eMinMaxNotAllowed,
     nsMediaFeature::eBoolInteger,
-    nsMediaFeature::eNoRequirements,
+    nsMediaFeature::eUserAgentAndChromeOnly,
     { &nsGkAtoms::windows_classic },
     GetSystemMetric
   },
   {
     &nsGkAtoms::_moz_windows_glass,
     nsMediaFeature::eMinMaxNotAllowed,
     nsMediaFeature::eBoolInteger,
-    nsMediaFeature::eNoRequirements,
+    nsMediaFeature::eUserAgentAndChromeOnly,
     { &nsGkAtoms::windows_glass },
     GetSystemMetric
   },
   {
     &nsGkAtoms::_moz_touch_enabled,
     nsMediaFeature::eMinMaxNotAllowed,
     nsMediaFeature::eBoolInteger,
+    // TODO(emilio): Unship (at least from content pages) once bug 1035774 is
+    // fixed.
     nsMediaFeature::eNoRequirements,
     { &nsGkAtoms::touch_enabled },
     GetSystemMetric
   },
   {
     &nsGkAtoms::_moz_menubar_drag,
     nsMediaFeature::eMinMaxNotAllowed,
     nsMediaFeature::eBoolInteger,
-    nsMediaFeature::eNoRequirements,
+    nsMediaFeature::eUserAgentAndChromeOnly,
     { &nsGkAtoms::menubar_drag },
     GetSystemMetric
   },
   {
     &nsGkAtoms::_moz_windows_theme,
     nsMediaFeature::eMinMaxNotAllowed,
     nsMediaFeature::eIdent,
+    // TODO(emilio): Unship.
     nsMediaFeature::eNoRequirements,
     { nullptr },
     GetWindowsTheme
   },
   {
     &nsGkAtoms::_moz_os_version,
     nsMediaFeature::eMinMaxNotAllowed,
     nsMediaFeature::eIdent,
+    // TODO(emilio): Unship.
     nsMediaFeature::eNoRequirements,
     { nullptr },
     GetOperatingSystemVersion
   },
 
   {
     &nsGkAtoms::_moz_swipe_animation_enabled,
     nsMediaFeature::eMinMaxNotAllowed,
     nsMediaFeature::eBoolInteger,
-    nsMediaFeature::eNoRequirements,
+    nsMediaFeature::eUserAgentAndChromeOnly,
     { &nsGkAtoms::swipe_animation_enabled },
     GetSystemMetric
   },
 
   {
     &nsGkAtoms::_moz_physical_home_button,
     nsMediaFeature::eMinMaxNotAllowed,
     nsMediaFeature::eBoolInteger,
-    nsMediaFeature::eNoRequirements,
+    nsMediaFeature::eUserAgentAndChromeOnly,
     { &nsGkAtoms::physical_home_button },
     GetSystemMetric
   },
 
   // Internal -moz-is-glyph media feature: applies only inside SVG glyphs.
   // Internal because it is really only useful in the user agent anyway
   //  and therefore not worth standardizing.
+  //
+  // TODO(emilio): There's nothing that makes this internal at all!
   {
     &nsGkAtoms::_moz_is_glyph,
     nsMediaFeature::eMinMaxNotAllowed,
     nsMediaFeature::eBoolInteger,
     nsMediaFeature::eNoRequirements,
     { nullptr },
     GetIsGlyph
   },
--- a/layout/style/nsMediaFeatures.h
+++ b/layout/style/nsMediaFeatures.h
@@ -52,17 +52,19 @@ struct nsMediaFeature
     // media feature to be active.
     eNoRequirements = 0,
     eHasWebkitPrefix = 1 << 0, // Feature name must start w/ "-webkit-", even
                                // before any "min-"/"max-" qualifier.
 
     // Feature is only supported if the pref
     // "layout.css.prefixes.device-pixel-ratio-webkit" is enabled.
     // (Should only be used for -webkit-device-pixel-ratio.)
-    eWebkitDevicePixelRatioPrefEnabled = 1 << 1
+    eWebkitDevicePixelRatioPrefEnabled = 1 << 1,
+    // Feature is only usable from UA sheets and chrome:// urls.
+    eUserAgentAndChromeOnly = 1 << 2,
   };
   uint8_t mReqFlags;
 
   union {
     // In static arrays, it's the first member that's initialized.  We
     // need that to be void* so we can initialize both other types.
     // This member should never be accessed by name.
     const void* mInitializer_;
--- a/layout/style/test/chrome/bug418986-2.js
+++ b/layout/style/test/chrome/bug418986-2.js
@@ -29,33 +29,40 @@ var expected_values = [
   ["width", window.innerWidth + "px", window.innerWidth + "px"],
   ["-moz-device-pixel-ratio", window.devicePixelRatio, 1],
   ["-moz-device-orientation", screen.width > screen.height ?
                                 "landscape" : "portrait",
                               window.innerWidth > window.innerHeight ?
                                 "landscape" : "portrait"]
 ];
 
-// These media queries return value 0 or 1 when the pref is off.
+// These media queries return value 0 or 1 when the pref is off, or never match
+// due to they being not available in non-chrome / UA pages.
+//
 // When the pref is on, they should not match.
 var suppressed_toggles = [
   "-moz-mac-graphite-theme",
   // Not available on most OSs.
 //  "-moz-maemo-classic",
   "-moz-scrollbar-end-backward",
   "-moz-scrollbar-end-forward",
   "-moz-scrollbar-start-backward",
   "-moz-scrollbar-start-forward",
   "-moz-scrollbar-thumb-proportional",
   "-moz-touch-enabled",
   "-moz-windows-compositor",
   "-moz-windows-default-theme",
   "-moz-windows-glass",
 ];
 
+// The toggles enabled in content pages, which would actually test to 0 or 1.
+const toggles_enabled_in_content = [
+  "-moz-touch-enabled",
+];
+
 // Possible values for '-moz-os-version'
 var windows_versions = [
   "windows-win7",
   "windows-win8",
   "windows-win10",
 ];
 
 // Possible values for '-moz-windows-theme'
@@ -99,17 +106,17 @@ var testMatch = function (key, val) {
 };
 
 // __testToggles(resisting)__.
 // Test whether we are able to match the "toggle" media queries.
 var testToggles = function (resisting) {
   suppressed_toggles.forEach(
     function (key) {
       var exists = keyValMatches(key, 0) || keyValMatches(key, 1);
-      if (resisting) {
+      if (resisting || toggles_enabled_in_content.indexOf(key) === -1) {
          ok(!exists, key + " should not exist.");
       } else {
          ok(exists, key + " should exist.");
       }
     });
 };
 
 // __testWindowsSpecific__.
@@ -195,17 +202,18 @@ var generateCSSLines = function (resisti
   let lines = ".spoof { background-color: red;}\n";
   expected_values.forEach(
     function ([key, offVal, onVal]) {
       lines += mediaQueryCSSLine(key, resisting ? onVal : offVal, "green");
     });
   lines += ".suppress { background-color: " + (resisting ? "green" : "red") + ";}\n";
   suppressed_toggles.forEach(
     function (key) {
-      lines += suppressedMediaQueryCSSLine(key, resisting ? "red" : "green");
+      let color = resisting ? "red" : "green";
+      lines += suppressedMediaQueryCSSLine(key, color);
     });
   if (OS === "WINNT") {
     lines += ".windows { background-color: " + (resisting ? "green" : "red") + ";}\n";
     lines += windows_versions.map(val => "(-moz-os-version: " + val + ")").join(", ") +
              " { #-moz-os-version { background-color: " + (resisting ? "red" : "green") + ";} }\n";
     lines += windows_themes.map(val => "(-moz-windows-theme: " + val + ")").join(",") +
              " { #-moz-windows-theme { background-color: " + (resisting ? "red" : "green") + ";} }\n";
   }
--- a/layout/style/test/test_media_queries.html
+++ b/layout/style/test/test_media_queries.html
@@ -627,64 +627,64 @@ function run() {
 
   // Assume we don't support grid devices
   should_not_apply("(grid)");
   should_apply("(grid: 0)");
   should_not_apply("(grid: 1)");
   should_not_apply("(grid: 2)");
   should_not_apply("(grid: -1)");
 
-  // System metrics
-  expression_should_be_parseable("-moz-scrollbar-start-backward");
-  expression_should_be_parseable("-moz-scrollbar-start-forward");
-  expression_should_be_parseable("-moz-scrollbar-end-backward");
-  expression_should_be_parseable("-moz-scrollbar-end-forward");
-  expression_should_be_parseable("-moz-scrollbar-thumb-proportional");
-  expression_should_be_parseable("-moz-overlay-scrollbars");
-  expression_should_be_parseable("-moz-windows-default-theme");
-  expression_should_be_parseable("-moz-mac-graphite-theme");
-  expression_should_be_parseable("-moz-mac-yosemite-theme");
-  expression_should_be_parseable("-moz-windows-accent-color-in-titlebar");
-  expression_should_be_parseable("-moz-windows-compositor");
-  expression_should_be_parseable("-moz-windows-classic");
-  expression_should_be_parseable("-moz-windows-glass");
+  // System metrics (internal, so none of them should be parseable from this test).
+  expression_should_not_be_parseable("-moz-scrollbar-start-backward");
+  expression_should_not_be_parseable("-moz-scrollbar-start-forward");
+  expression_should_not_be_parseable("-moz-scrollbar-end-backward");
+  expression_should_not_be_parseable("-moz-scrollbar-end-forward");
+  expression_should_not_be_parseable("-moz-scrollbar-thumb-proportional");
+  expression_should_not_be_parseable("-moz-overlay-scrollbars");
+  expression_should_not_be_parseable("-moz-windows-default-theme");
+  expression_should_not_be_parseable("-moz-mac-graphite-theme");
+  expression_should_not_be_parseable("-moz-mac-yosemite-theme");
+  expression_should_not_be_parseable("-moz-windows-accent-color-in-titlebar");
+  expression_should_not_be_parseable("-moz-windows-compositor");
+  expression_should_not_be_parseable("-moz-windows-classic");
+  expression_should_not_be_parseable("-moz-windows-glass");
+  expression_should_not_be_parseable("-moz-swipe-animation-enabled");
   expression_should_be_parseable("-moz-touch-enabled");
-  expression_should_be_parseable("-moz-swipe-animation-enabled");
 
-  expression_should_be_parseable("-moz-scrollbar-start-backward: 0");
-  expression_should_be_parseable("-moz-scrollbar-start-forward: 0");
-  expression_should_be_parseable("-moz-scrollbar-end-backward: 0");
-  expression_should_be_parseable("-moz-scrollbar-end-forward: 0");
-  expression_should_be_parseable("-moz-scrollbar-thumb-proportional: 0");
-  expression_should_be_parseable("-moz-overlay-scrollbars: 0");
-  expression_should_be_parseable("-moz-windows-default-theme: 0");
-  expression_should_be_parseable("-moz-mac-graphite-theme: 0");
-  expression_should_be_parseable("-moz-mac-yosemite-theme: 0");
-  expression_should_be_parseable("-moz-windows-accent-color-in-titlebar: 0");
-  expression_should_be_parseable("-moz-windows-compositor: 0");
-  expression_should_be_parseable("-moz-windows-classic: 0");
-  expression_should_be_parseable("-moz-windows-glass: 0");
+  expression_should_not_be_parseable("-moz-scrollbar-start-backward: 0");
+  expression_should_not_be_parseable("-moz-scrollbar-start-forward: 0");
+  expression_should_not_be_parseable("-moz-scrollbar-end-backward: 0");
+  expression_should_not_be_parseable("-moz-scrollbar-end-forward: 0");
+  expression_should_not_be_parseable("-moz-scrollbar-thumb-proportional: 0");
+  expression_should_not_be_parseable("-moz-overlay-scrollbars: 0");
+  expression_should_not_be_parseable("-moz-windows-default-theme: 0");
+  expression_should_not_be_parseable("-moz-mac-graphite-theme: 0");
+  expression_should_not_be_parseable("-moz-mac-yosemite-theme: 0");
+  expression_should_not_be_parseable("-moz-windows-accent-color-in-titlebar: 0");
+  expression_should_not_be_parseable("-moz-windows-compositor: 0");
+  expression_should_not_be_parseable("-moz-windows-classic: 0");
+  expression_should_not_be_parseable("-moz-windows-glass: 0");
+  expression_should_not_be_parseable("-moz-swipe-animation-enabled: 0");
   expression_should_be_parseable("-moz-touch-enabled: 0");
-  expression_should_be_parseable("-moz-swipe-animation-enabled: 0");
 
-  expression_should_be_parseable("-moz-scrollbar-start-backward: 1");
-  expression_should_be_parseable("-moz-scrollbar-start-forward: 1");
-  expression_should_be_parseable("-moz-scrollbar-end-backward: 1");
-  expression_should_be_parseable("-moz-scrollbar-end-forward: 1");
-  expression_should_be_parseable("-moz-scrollbar-thumb-proportional: 1");
-  expression_should_be_parseable("-moz-overlay-scrollbars: 1");
-  expression_should_be_parseable("-moz-windows-default-theme: 1");
-  expression_should_be_parseable("-moz-mac-graphite-theme: 1");
-  expression_should_be_parseable("-moz-mac-yosemite-theme: 1");
-  expression_should_be_parseable("-moz-windows-accent-color-in-titlebar: 1");
-  expression_should_be_parseable("-moz-windows-compositor: 1");
-  expression_should_be_parseable("-moz-windows-classic: 1");
-  expression_should_be_parseable("-moz-windows-glass: 1");
+  expression_should_not_be_parseable("-moz-scrollbar-start-backward: 1");
+  expression_should_not_be_parseable("-moz-scrollbar-start-forward: 1");
+  expression_should_not_be_parseable("-moz-scrollbar-end-backward: 1");
+  expression_should_not_be_parseable("-moz-scrollbar-end-forward: 1");
+  expression_should_not_be_parseable("-moz-scrollbar-thumb-proportional: 1");
+  expression_should_not_be_parseable("-moz-overlay-scrollbars: 1");
+  expression_should_not_be_parseable("-moz-windows-default-theme: 1");
+  expression_should_not_be_parseable("-moz-mac-graphite-theme: 1");
+  expression_should_not_be_parseable("-moz-mac-yosemite-theme: 1");
+  expression_should_not_be_parseable("-moz-windows-accent-color-in-titlebar: 1");
+  expression_should_not_be_parseable("-moz-windows-compositor: 1");
+  expression_should_not_be_parseable("-moz-windows-classic: 1");
+  expression_should_not_be_parseable("-moz-windows-glass: 1");
+  expression_should_not_be_parseable("-moz-swipe-animation-enabled: 1");
   expression_should_be_parseable("-moz-touch-enabled: 1");
-  expression_should_be_parseable("-moz-swipe-animation-enabled: 1");
 
   expression_should_not_be_parseable("-moz-scrollbar-start-backward: -1");
   expression_should_not_be_parseable("-moz-scrollbar-start-forward: -1");
   expression_should_not_be_parseable("-moz-scrollbar-end-backward: -1");
   expression_should_not_be_parseable("-moz-scrollbar-end-forward: -1");
   expression_should_not_be_parseable("-moz-scrollbar-thumb-proportional: -1");
   expression_should_not_be_parseable("-moz-overlay-scrollbars: -1");
   expression_should_not_be_parseable("-moz-windows-default-theme: -1");