Bug 1288572: Hide -moz- display values from content behind a pref. r?xidorn draft
authorEmilio Cobos Álvarez <emilio@crisal.io>
Sat, 02 Jun 2018 19:35:12 +0200
changeset 803335 9cd8445b6b4ef3a41f99464b891a6021fb73120b
parent 803294 3290f32071d6667d4fb503c867b2d9abb66c6ad0
child 803336 8285980a0b706adb655423133aeb1b72f8845f17
push id112074
push userbmo:emilio@crisal.io
push dateSun, 03 Jun 2018 11:02:15 +0000
reviewersxidorn
bugs1288572
milestone62.0a1
Bug 1288572: Hide -moz- display values from content behind a pref. r?xidorn MozReview-Commit-ID: HDQPub043H1
layout/style/test/mochitest.ini
layout/style/test/test_layout_css_xul_display_values_content_enabled.html
layout/style/test/test_non_content_accessible_values.html
modules/libpref/init/StaticPrefList.h
servo/components/style/properties/longhand/box.mako.rs
servo/components/style/values/specified/box.rs
--- a/layout/style/test/mochitest.ini
+++ b/layout/style/test/mochitest.ini
@@ -236,29 +236,31 @@ skip-if = verify
 skip-if = toolkit == 'android'
 [test_inherit_storage.html]
 [test_initial_computation.html]
 skip-if = toolkit == 'android'
 [test_initial_storage.html]
 [test_invalidation_basic.html]
 [test_keyframes_rules.html]
 [test_keyframes_vendor_prefix.html]
+[test_layout_css_xul_display_values_content_enabled.html]
 [test_load_events_on_stylesheets.html]
 support-files = slow_broken_sheet.sjs slow_ok_sheet.sjs
 [test_logical_properties.html]
 [test_media_queries.html]
 skip-if = android_version == '18' #debug-only failure; timed out #Android 4.3 aws only; bug 1030419
 [test_media_queries_dynamic.html]
 [test_media_queries_dynamic_xbl.html]
 [test_media_query_list.html]
 [test_media_query_serialization.html]
 [test_moz_device_pixel_ratio.html]
 [test_namespace_rule.html]
 [test_non_content_accessible_properties.html]
 [test_non_content_accessible_pseudos.html]
+[test_non_content_accessible_values.html]
 [test_of_type_selectors.xhtml]
 [test_overscroll_behavior_pref.html]
 [test_page_parser.html]
 [test_parse_eof.html]
 [test_parse_ident.html]
 [test_parse_rule.html]
 [test_parse_url.html]
 [test_parser_diagnostics_unprintables.html]
new file mode 100644
--- /dev/null
+++ b/layout/style/test/test_layout_css_xul_display_values_content_enabled.html
@@ -0,0 +1,34 @@
+<!doctype html>
+<script src="/tests/SimpleTest/SimpleTest.js"></script>
+<div></div>
+<script>
+const VALUES = [
+  "-moz-box",
+  "-moz-inline-box",
+  "-moz-grid",
+  "-moz-inline-grid",
+  "-moz-grid-group",
+  "-moz-grid-line",
+  "-moz-stack",
+  "-moz-inline-stack",
+  "-moz-deck",
+  "-moz-popup",
+  "-moz-groupbox",
+];
+
+SimpleTest.waitForExplicitFinish();
+SpecialPowers.pushPrefEnv(
+  {"set": [["layout.css.xul-display-values.content.enabled", true]]}
+).then(runTest);
+
+function runTest() {
+  const div = document.querySelector("div");
+  for (const value of VALUES) {
+    div.style.display = value;
+    is(div.style.display, value);
+    is(getComputedStyle(div).display, value);
+    ok(CSS.supports("display", value));
+  }
+  SimpleTest.finish();
+}
+</script>
new file mode 100644
--- /dev/null
+++ b/layout/style/test/test_non_content_accessible_values.html
@@ -0,0 +1,64 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style id="sheet"></style>
+<div></div>
+<script>
+const NON_CONTENT_ACCESSIBLE_VALUES = {
+  "display": [
+    "-moz-box",
+    "-moz-inline-box",
+    "-moz-grid",
+    "-moz-inline-grid",
+    "-moz-grid-group",
+    "-moz-grid-line",
+    "-moz-stack",
+    "-moz-inline-stack",
+    "-moz-deck",
+    "-moz-popup",
+    "-moz-groupbox",
+  ],
+};
+
+const sheet = document.getElementById("sheet");
+const div = document.querySelector("div");
+
+test(function() {
+  sheet.textContent = `div { color: initial }`;
+  assert_equals(sheet.sheet.cssRules[0].style.length, 1);
+}, "sanity");
+
+for (const prop in NON_CONTENT_ACCESSIBLE_VALUES) {
+  test(function() {
+    const values = NON_CONTENT_ACCESSIBLE_VALUES[prop];
+    for (const value of values) {
+      sheet.textContent = `div { ${prop}: ${value} }`;
+      const block = sheet.sheet.cssRules[0].style;
+      assert_equals(
+        block.length,
+        0,
+        `${prop}: ${value} should not be parsed in content`
+      );
+      block.setProperty(prop, value);
+      assert_equals(
+        block.length,
+        0,
+        `${prop}: ${value} should not be settable via CSSOM in content`
+      );
+      div.style.setProperty(prop, value);
+      assert_equals(
+        div.style.length,
+        0,
+        `${prop}: ${value} should not be settable via CSSOM in content (inline style)`
+      );
+      assert_not_equals(
+        getComputedStyle(div).getPropertyValue(prop),
+        value,
+        `${prop}: ${value} should not be settable via CSSOM in content (gcs)`
+      );
+
+      assert_false(CSS.supports(prop, value), `${prop}: ${value} should not claim to be supported`)
+    }
+  }, prop + " non-accessible values")
+}
+</script>
--- a/modules/libpref/init/StaticPrefList.h
+++ b/modules/libpref/init/StaticPrefList.h
@@ -249,16 +249,22 @@ VARCACHE_PREF(
 #endif
 VARCACHE_PREF(
   "layout.css.moz-document.url-prefix-hack.enabled",
    layout_css_moz_document_url_prefix_hack_enabled,
   bool, PREF_VALUE
 )
 #undef PREF_VALUE
 
+VARCACHE_PREF(
+  "layout.css.xul-display-values.content.enabled",
+   layout_css_xul_display_values_content_enabled,
+  bool, false
+)
+
 // Is support for CSS "grid-template-{columns,rows}: subgrid X" enabled?
 VARCACHE_PREF(
   "layout.css.grid-template-subgrid-value.enabled",
    layout_css_grid_template_subgrid_value_enabled,
   bool, false
 )
 
 // Is support for variation fonts enabled?
--- a/servo/components/style/properties/longhand/box.mako.rs
+++ b/servo/components/style/properties/longhand/box.mako.rs
@@ -4,27 +4,24 @@
 
 <%namespace name="helpers" file="/helpers.mako.rs" />
 <% from data import Keyword, Method, to_rust_ident, to_camel_case%>
 
 <% data.new_style_struct("Box",
                          inherited=False,
                          gecko_name="Display") %>
 
-// TODO(SimonSapin): don't parse `inline-table`, since we don't support it
-//
 // We allow "display" to apply to placeholders because we need to make the
 // placeholder pseudo-element an inline-block in the UA stylesheet in Gecko.
 ${helpers.predefined_type(
     "display",
     "Display",
     "computed::Display::inline()",
     initial_specified_value="specified::Display::inline()",
     animation_value_type="discrete",
-    needs_context=False,
     flags="APPLIES_TO_PLACEHOLDER",
     spec="https://drafts.csswg.org/css-display/#propdef-display",
     servo_restyle_damage="rebuild_and_reflow"
 )}
 
 // FIXME(emilio): Listing all the display values here is very unfortunate, we should teach C++ to use the
 // Rust enum directly, or generate the conversions to `StyleDisplay`.
 ${helpers.gecko_keyword_conversion(
--- a/servo/components/style/values/specified/box.rs
+++ b/servo/components/style/values/specified/box.rs
@@ -13,16 +13,27 @@ use std::fmt::{self, Write};
 use style_traits::{CssWriter, KeywordsCollectFn, ParseError, StyleParseErrorKind, SpecifiedValueInfo, ToCss};
 use values::{CustomIdent, KeyframesName};
 use values::generics::box_::AnimationIterationCount as GenericAnimationIterationCount;
 use values::generics::box_::Perspective as GenericPerspective;
 use values::generics::box_::VerticalAlign as GenericVerticalAlign;
 use values::specified::{AllowQuirks, Number};
 use values::specified::length::{LengthOrPercentage, NonNegativeLength};
 
+#[cfg(feature = "gecko")]
+fn moz_display_values_enabled_on_content(context: &ParserContext) -> bool {
+    use gecko_bindings::structs;
+    use stylesheets::Origin;
+    context.stylesheet_origin == Origin::UserAgent ||
+    context.chrome_rules_enabled() ||
+    unsafe {
+        structs::StaticPrefs_sVarCache_layout_css_xul_display_values_content_enabled
+    }
+}
+
 #[allow(missing_docs)]
 #[derive(Clone, Copy, Debug, Eq, Hash, MallocSizeOf, Parse, PartialEq,
          SpecifiedValueInfo, ToComputedValue, ToCss)]
 #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
 /// Defines an element’s display type, which consists of
 /// the two basic qualities of how an element generates boxes
 /// <https://drafts.csswg.org/css-display/#propdef-display>
 pub enum Display {
@@ -63,36 +74,47 @@ pub enum Display {
     Contents,
     #[cfg(feature = "gecko")]
     FlowRoot,
     #[cfg(feature = "gecko")]
     WebkitBox,
     #[cfg(feature = "gecko")]
     WebkitInlineBox,
     #[cfg(feature = "gecko")]
+    #[css(parse_condition = "moz_display_values_enabled_on_content")]
     MozBox,
     #[cfg(feature = "gecko")]
+    #[css(parse_condition = "moz_display_values_enabled_on_content")]
     MozInlineBox,
     #[cfg(feature = "gecko")]
+    #[css(parse_condition = "moz_display_values_enabled_on_content")]
     MozGrid,
     #[cfg(feature = "gecko")]
+    #[css(parse_condition = "moz_display_values_enabled_on_content")]
     MozInlineGrid,
     #[cfg(feature = "gecko")]
+    #[css(parse_condition = "moz_display_values_enabled_on_content")]
     MozGridGroup,
     #[cfg(feature = "gecko")]
+    #[css(parse_condition = "moz_display_values_enabled_on_content")]
     MozGridLine,
     #[cfg(feature = "gecko")]
+    #[css(parse_condition = "moz_display_values_enabled_on_content")]
     MozStack,
     #[cfg(feature = "gecko")]
+    #[css(parse_condition = "moz_display_values_enabled_on_content")]
     MozInlineStack,
     #[cfg(feature = "gecko")]
+    #[css(parse_condition = "moz_display_values_enabled_on_content")]
     MozDeck,
     #[cfg(feature = "gecko")]
+    #[css(parse_condition = "moz_display_values_enabled_on_content")]
     MozPopup,
     #[cfg(feature = "gecko")]
+    #[css(parse_condition = "moz_display_values_enabled_on_content")]
     MozGroupbox,
 }
 
 impl Display {
     /// The initial display value.
     #[inline]
     pub fn inline() -> Self {
         Display::Inline