Bug 1379582 - Disable frames() timing function using a pref on release/beta channels; r?hiro
authorBrian Birtles <birtles@gmail.com>
Tue, 11 Jul 2017 12:38:58 +0900
changeset 1181139 09247e64325d98b085fc504bc5a272a127d005f3
parent 1180853 5d794bf4c4653153e602631f1b8818acd559d8f5
child 1181140 46021312a2e345493ee4d74f4c6c6ef2a13abded
child 1181142 7afc3700f5c19c1bb4fdfcabaef51ad18c64a700
push id203839
push userbbirtles@mozilla.com
push dateTue, 11 Jul 2017 03:39:43 +0000
treeherdertry@46021312a2e3 [default view] [failures only]
reviewershiro
bugs1379582
milestone56.0a1
Bug 1379582 - Disable frames() timing function using a pref on release/beta channels; r?hiro MozReview-Commit-ID: LC1rEkmCR29
layout/style/ServoBindings.cpp
layout/style/ServoBindings.h
layout/style/nsCSSParser.cpp
layout/style/test/property_database.js
modules/libpref/init/all.js
servo/components/style/gecko/generated/bindings.rs
servo/components/style/values/specified/transform.rs
testing/web-platform/meta/css-timing/__dir__.ini
testing/web-platform/meta/web-animations/__dir__.ini
--- a/layout/style/ServoBindings.cpp
+++ b/layout/style/ServoBindings.cpp
@@ -47,16 +47,17 @@
 
 #include "mozilla/DeclarationBlockInlines.h"
 #include "mozilla/EffectCompositor.h"
 #include "mozilla/EffectSet.h"
 #include "mozilla/EventStates.h"
 #include "mozilla/GeckoStyleContext.h"
 #include "mozilla/Keyframe.h"
 #include "mozilla/Mutex.h"
+#include "mozilla/Preferences.h"
 #include "mozilla/ServoElementSnapshot.h"
 #include "mozilla/ServoRestyleManager.h"
 #include "mozilla/StyleAnimationValue.h"
 #include "mozilla/SystemGroup.h"
 #include "mozilla/ServoMediaList.h"
 #include "mozilla/RWLock.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/ElementInlines.h"
@@ -81,16 +82,17 @@ using namespace mozilla::dom;
   }
 #include "mozilla/ServoArcTypeList.h"
 #undef SERVO_ARC_TYPE
 
 
 static Mutex* sServoFontMetricsLock = nullptr;
 static RWLock* sServoLangFontPrefsLock = nullptr;
 
+static bool sFramesTimingFunctionEnabled;
 
 static
 const nsFont*
 ThreadSafeGetDefaultFontHelper(const nsPresContext* aPresContext,
                                nsIAtom* aLanguage, uint8_t aGenericId)
 {
   bool needsCache = false;
   const nsFont* retval;
@@ -756,16 +758,21 @@ Gecko_GetPositionInSegment(RawGeckoAnima
   double positionInSegment =
     (aProgress - aSegment->mFromKey) / (aSegment->mToKey - aSegment->mFromKey);
 
   return ComputedTimingFunction::GetPortion(aSegment->mTimingFunction,
                                             positionInSegment,
                                             aBeforeFlag);
 }
 
+bool
+Gecko_IsFramesTimingEnabled() {
+  return sFramesTimingFunctionEnabled;
+}
+
 RawServoAnimationValueBorrowedOrNull
 Gecko_AnimationGetBaseStyle(void* aBaseStyles, nsCSSPropertyID aProperty)
 {
   auto base =
     static_cast<nsRefPtrHashtable<nsUint32HashKey, RawServoAnimationValue>*>
       (aBaseStyles);
   return base->GetWeak(aProperty);
 }
@@ -2331,16 +2338,19 @@ Gecko_XBLBinding_InheritsStyle(RawGeckoX
 void
 InitializeServo()
 {
   URLExtraData::InitDummy();
   Servo_Initialize(URLExtraData::Dummy());
 
   sServoFontMetricsLock = new Mutex("Gecko_GetFontMetrics");
   sServoLangFontPrefsLock = new RWLock("nsPresContext::GetDefaultFont");
+
+  Preferences::AddBoolVarCache(&sFramesTimingFunctionEnabled,
+                               "layout.css.frames-timing.enabled");
 }
 
 void
 ShutdownServo()
 {
   delete sServoFontMetricsLock;
   delete sServoLangFontPrefsLock;
   Servo_Shutdown();
--- a/layout/style/ServoBindings.h
+++ b/layout/style/ServoBindings.h
@@ -232,16 +232,17 @@ nsCSSPropertyID Gecko_ElementTransitions
 RawServoAnimationValueBorrowedOrNull Gecko_ElementTransitions_EndValueAt(
   RawGeckoElementBorrowed aElementOrPseudo,
   size_t aIndex);
 double Gecko_GetProgressFromComputedTiming(RawGeckoComputedTimingBorrowed aComputedTiming);
 double Gecko_GetPositionInSegment(
   RawGeckoAnimationPropertySegmentBorrowed aSegment,
   double aProgress,
   mozilla::ComputedTimingFunction::BeforeFlag aBeforeFlag);
+bool Gecko_IsFramesTimingEnabled();
 // Get servo's AnimationValue for |aProperty| from the cached base style
 // |aBaseStyles|.
 // |aBaseStyles| is nsRefPtrHashtable<nsUint32HashKey, RawServoAnimationValue>.
 // We use void* to avoid exposing nsRefPtrHashtable in FFI.
 RawServoAnimationValueBorrowedOrNull Gecko_AnimationGetBaseStyle(
   void* aBaseStyles,
   nsCSSPropertyID aProperty);
 void Gecko_StyleTransition_SetUnsupportedProperty(
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -71,16 +71,17 @@ using namespace mozilla::css;
 typedef nsCSSProps::KTableEntry KTableEntry;
 
 // pref-backed bool values (hooked up in nsCSSParser::Startup)
 static bool sOpentypeSVGEnabled;
 static bool sWebkitPrefixedAliasesEnabled;
 static bool sWebkitDevicePixelRatioEnabled;
 static bool sMozGradientsEnabled;
 static bool sControlCharVisibility;
+static bool sFramesTimingFunctionEnabled;
 
 const uint32_t
 nsCSSProps::kParserVariantTable[eCSSProperty_COUNT_no_shorthands] = {
 #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, \
                  stylestruct_, stylestructoffset_, animtype_)                 \
   parsevariant_,
 #define CSS_PROP_LIST_INCLUDE_LOGICAL
 #include "nsCSSPropList.h"
@@ -7852,17 +7853,18 @@ CSSParserImpl::ParseVariant(nsCSSValue& 
     }
     if (tk->mIdent.LowerCaseEqualsLiteral("steps")) {
       if (!ParseTransitionStepTimingFunctionValues(aValue)) {
         SkipUntil(')');
         return CSSParseResult::Error;
       }
       return CSSParseResult::Ok;
     }
-    if (tk->mIdent.LowerCaseEqualsLiteral("frames")) {
+    if (sFramesTimingFunctionEnabled &&
+        tk->mIdent.LowerCaseEqualsLiteral("frames")) {
       if (!ParseTransitionFramesTimingFunctionValues(aValue)) {
         SkipUntil(')');
         return CSSParseResult::Error;
       }
       return CSSParseResult::Ok;
     }
   }
   if ((aVariantMask & VARIANT_CALC) &&
@@ -17833,16 +17835,18 @@ nsCSSParser::Startup()
   Preferences::AddBoolVarCache(&sWebkitPrefixedAliasesEnabled,
                                "layout.css.prefixes.webkit");
   Preferences::AddBoolVarCache(&sWebkitDevicePixelRatioEnabled,
                                "layout.css.prefixes.device-pixel-ratio-webkit");
   Preferences::AddBoolVarCache(&sMozGradientsEnabled,
                                "layout.css.prefixes.gradients");
   Preferences::AddBoolVarCache(&sControlCharVisibility,
                                "layout.css.control-characters.visible");
+  Preferences::AddBoolVarCache(&sFramesTimingFunctionEnabled,
+                               "layout.css.frames-timing.enabled");
 }
 
 nsCSSParser::nsCSSParser(mozilla::css::Loader* aLoader,
                          CSSStyleSheet* aSheet)
 {
   CSSParserImpl *impl = gFreeList;
   if (impl) {
     gFreeList = impl->mNextFree;
--- a/layout/style/test/property_database.js
+++ b/layout/style/test/property_database.js
@@ -1023,18 +1023,18 @@ var gCSSProperties = {
     other_values: [ "paused", "running, running", "paused, running", "paused, paused", "running, paused", "paused, running, running, running, paused, running" ],
     invalid_values: [ "0" ]
   },
   "animation-timing-function": {
     domProp: "animationTimingFunction",
     inherited: false,
     type: CSS_TYPE_LONGHAND,
     initial_values: [ "ease" ],
-    other_values: [ "cubic-bezier(0.25, 0.1, 0.25, 1.0)", "linear", "ease-in", "ease-out", "ease-in-out", "linear, ease-in, cubic-bezier(0.1, 0.2, 0.8, 0.9)", "cubic-bezier(0.5, 0.5, 0.5, 0.5)", "cubic-bezier(0.25, 1.5, 0.75, -0.5)", "step-start", "step-end", "steps(1)", "steps(2, start)", "steps(386)", "steps(3, end)", "frames(2)", "frames(1000)", "frames( 2 )" ],
-    invalid_values: [ "none", "auto", "cubic-bezier(0.25, 0.1, 0.25)", "cubic-bezier(0.25, 0.1, 0.25, 0.25, 1.0)", "cubic-bezier(-0.5, 0.5, 0.5, 0.5)", "cubic-bezier(1.5, 0.5, 0.5, 0.5)", "cubic-bezier(0.5, 0.5, -0.5, 0.5)", "cubic-bezier(0.5, 0.5, 1.5, 0.5)", "steps(2, step-end)", "steps(0)", "steps(-2)", "steps(0, step-end, 1)", "frames(1)", "frames(-2)", "frames", "frames()", "frames(,)", "frames(a)", "frames(2.0)", "frames(2.5)", "frames(2 3)" ]
+    other_values: [ "cubic-bezier(0.25, 0.1, 0.25, 1.0)", "linear", "ease-in", "ease-out", "ease-in-out", "linear, ease-in, cubic-bezier(0.1, 0.2, 0.8, 0.9)", "cubic-bezier(0.5, 0.5, 0.5, 0.5)", "cubic-bezier(0.25, 1.5, 0.75, -0.5)", "step-start", "step-end", "steps(1)", "steps(2, start)", "steps(386)", "steps(3, end)" ],
+    invalid_values: [ "none", "auto", "cubic-bezier(0.25, 0.1, 0.25)", "cubic-bezier(0.25, 0.1, 0.25, 0.25, 1.0)", "cubic-bezier(-0.5, 0.5, 0.5, 0.5)", "cubic-bezier(1.5, 0.5, 0.5, 0.5)", "cubic-bezier(0.5, 0.5, -0.5, 0.5)", "cubic-bezier(0.5, 0.5, 1.5, 0.5)", "steps(2, step-end)", "steps(0)", "steps(-2)", "steps(0, step-end, 1)" ]
   },
   "-moz-appearance": {
     domProp: "MozAppearance",
     inherited: false,
     type: CSS_TYPE_LONGHAND,
     initial_values: [ "none" ],
     other_values: [ "radio", "menulist" ],
     invalid_values: []
@@ -5698,16 +5698,24 @@ if (IsCSSPropertyPrefEnabled("layout.css
       "'wdth', 1" // comma within pair
     ],
     unbalanced_values: [
       "'wdth\" 1", "\"wdth' 1" // mismatched quotes
     ]
   }
 }
 
+if (IsCSSPropertyPrefEnabled("layout.css.frames-timing.enabled")) {
+  gCSSProperties["text-combine-upright"].other_values.push(
+    "frames(2)", "frames(1000)", "frames( 2 )");
+  gCSSProperties["text-combine-upright"].invalid_values.push(
+    "frames(1)", "frames(-2)", "frames", "frames()", "frames(,)",
+    "frames(a)", "frames(2.0)", "frames(2.5)", "frames(2 3)");
+}
+
 if (IsCSSPropertyPrefEnabled("svg.paint-order.enabled")) {
   gCSSProperties["paint-order"] = {
     domProp: "paintOrder",
     inherited: true,
     type: CSS_TYPE_LONGHAND,
     initial_values: [ "normal" ],
     other_values: [ "fill", "fill stroke", "fill stroke markers", "stroke markers fill" ],
     invalid_values: [ "fill stroke markers fill", "fill normal" ]
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -2845,16 +2845,23 @@ pref("layout.css.float-logical-values.en
 pref("layout.css.image-orientation.enabled", true);
 
 // Is support for the font-display @font-face descriptor enabled?
 pref("layout.css.font-display.enabled", false);
 
 // Is support for variation fonts enabled?
 pref("layout.css.font-variations.enabled", false);
 
+// Is support for the frames() timing function enabled?
+#ifdef RELEASE_OR_BETA
+pref("layout.css.frames-timing.enabled", false);
+#else
+pref("layout.css.frames-timing.enabled", true);
+#endif
+
 // Are sets of prefixed properties supported?
 pref("layout.css.prefixes.border-image", true);
 pref("layout.css.prefixes.transforms", true);
 pref("layout.css.prefixes.transitions", true);
 pref("layout.css.prefixes.animations", true);
 pref("layout.css.prefixes.box-sizing", true);
 pref("layout.css.prefixes.font-features", true);
 
--- a/servo/components/style/gecko/generated/bindings.rs
+++ b/servo/components/style/gecko/generated/bindings.rs
@@ -789,16 +789,19 @@ extern "C" {
      -> RawServoAnimationValueBorrowedOrNull;
 }
 extern "C" {
     pub fn Gecko_GetProgressFromComputedTiming(aComputedTiming:
                                                    RawGeckoComputedTimingBorrowed)
      -> f64;
 }
 extern "C" {
+    pub fn Gecko_IsFramesTimingEnabled() -> bool;
+}
+extern "C" {
     pub fn Gecko_GetPositionInSegment(aSegment:
                                           RawGeckoAnimationPropertySegmentBorrowed,
                                       aProgress: f64,
                                       aBeforeFlag:
                                           ComputedTimingFunction_BeforeFlag)
      -> f64;
 }
 extern "C" {
--- a/servo/components/style/values/specified/transform.rs
+++ b/servo/components/style/values/specified/transform.rs
@@ -1,16 +1,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 //! Specified types for CSS values that are related to transformations.
 
 use cssparser::Parser;
 use euclid::Point2D;
+#[cfg(feature = "gecko")] use gecko_bindings::bindings;
 use parser::{Parse, ParserContext};
 use selectors::parser::SelectorParseError;
 use style_traits::{ParseError, StyleParseError};
 use values::computed::{LengthOrPercentage as ComputedLengthOrPercentage, Context, ToComputedValue};
 use values::computed::transform::TimingFunction as ComputedTimingFunction;
 use values::generics::transform::{StepPosition, TimingFunction as GenericTimingFunction};
 use values::generics::transform::{TimingKeyword, TransformOrigin as GenericTransformOrigin};
 use values::specified::{Integer, Number};
@@ -167,18 +168,24 @@ impl Parse for TimingFunction {
                     let steps = Integer::parse_positive(context, i)?;
                     let position = i.try(|i| {
                         i.expect_comma()?;
                         StepPosition::parse(i)
                     }).unwrap_or(StepPosition::End);
                     Ok(GenericTimingFunction::Steps(steps, position))
                 },
                 "frames" => {
-                    let frames = Integer::parse_with_minimum(context, i, 2)?;
-                    Ok(GenericTimingFunction::Frames(frames))
+                    if cfg!(feature = "gecko") &&
+                        unsafe { !bindings::Gecko_IsFramesTimingEnabled() }
+                    {
+                       Err(())
+                    } else {
+                        let frames = Integer::parse_with_minimum(context, i, 2)?;
+                        Ok(GenericTimingFunction::Frames(frames))
+                    }
                 },
                 _ => Err(()),
             }).map_err(|()| StyleParseError::UnexpectedFunction(function).into())
         })
     }
 }
 
 impl ToComputedValue for TimingFunction {
--- a/testing/web-platform/meta/css-timing/__dir__.ini
+++ b/testing/web-platform/meta/css-timing/__dir__.ini
@@ -1,1 +1,2 @@
-prefs: [dom.animations-api.core.enabled:true]
\ No newline at end of file
+prefs: [dom.animations-api.core.enabled:true,
+        layout.css.frames-timing.enabled:true]
--- a/testing/web-platform/meta/web-animations/__dir__.ini
+++ b/testing/web-platform/meta/web-animations/__dir__.ini
@@ -1,1 +1,2 @@
-prefs: [dom.animations-api.core.enabled:true]
\ No newline at end of file
+prefs: [dom.animations-api.core.enabled:true,
+        layout.css.frames-timing.enabled:true]