From e207a805fc9fa7cfe93c98782016b456df251344 Mon Sep 17 00:00:00 2001 From: Hiroyuki Ikezoe Date: Fri, 28 Apr 2017 22:49:26 -0500 Subject: [PATCH 01/13] servo: Merge #16640 - Use FunctionKeyword for computed_value of timing function (from hiikezoe:timing-function); r=xidorn https://bugzilla.mozilla.org/show_bug.cgi?id=1358330 --- - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [X] These changes fix #15086 - [X] These changes do not require tests because mozilla-central has test cases. There might be some test cases in servo tree. Source-Repo: https://github.com/servo/servo Source-Revision: 93a513c06fe6e889efc5a3a52a1509298a81bb3e --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : a3f6ea4aaf3e6e44803cf28f06a1eb7f95bea784 --- servo/components/style/animation.rs | 18 ++++++-- .../sugar/ns_timing_function.rs | 46 +++++++++---------- .../style/properties/longhand/box.mako.rs | 44 ++++++++++++------ 3 files changed, 65 insertions(+), 43 deletions(-) diff --git a/servo/components/style/animation.rs b/servo/components/style/animation.rs index 110a73bbacdb..941db59cc852 100644 --- a/servo/components/style/animation.rs +++ b/servo/components/style/animation.rs @@ -339,19 +339,24 @@ impl PropertyAnimation { /// Update the given animation at a given point of progress. pub fn update(&self, style: &mut ComputedValues, time: f64) { - let progress = match self.timing_function { + let timing_function = match self.timing_function { + TransitionTimingFunction::Keyword(keyword) => + keyword.to_non_keyword_value(), + other => other, + }; + let progress = match timing_function { TransitionTimingFunction::CubicBezier(p1, p2) => { // See `WebCore::AnimationBase::solveEpsilon(double)` in WebKit. let epsilon = 1.0 / (200.0 * (self.duration.seconds() as f64)); Bezier::new(Point2D::new(p1.x as f64, p1.y as f64), Point2D::new(p2.x as f64, p2.y as f64)).solve(time, epsilon) - } + }, TransitionTimingFunction::Steps(steps, StartEnd::Start) => { (time * (steps as f64)).ceil() / (steps as f64) - } + }, TransitionTimingFunction::Steps(steps, StartEnd::End) => { (time * (steps as f64)).floor() / (steps as f64) - } + }, TransitionTimingFunction::Frames(frames) => { // https://drafts.csswg.org/css-timing/#frames-timing-functions let mut out = (time * (frames as f64)).floor() / ((frames - 1) as f64); @@ -367,7 +372,10 @@ impl PropertyAnimation { out = 1.0; } out - } + }, + TransitionTimingFunction::Keyword(_) => { + panic!("Keyword function should not appear") + }, }; self.property.update(style, progress); diff --git a/servo/components/style/gecko_bindings/sugar/ns_timing_function.rs b/servo/components/style/gecko_bindings/sugar/ns_timing_function.rs index 7b21d4bee594..69b64c3da524 100644 --- a/servo/components/style/gecko_bindings/sugar/ns_timing_function.rs +++ b/servo/components/style/gecko_bindings/sugar/ns_timing_function.rs @@ -9,6 +9,7 @@ use properties::longhands::transition_timing_function::single_value::SpecifiedVa use properties::longhands::transition_timing_function::single_value::computed_value::StartEnd; use properties::longhands::transition_timing_function::single_value::computed_value::T as ComputedTimingFunction; use std::mem; +use values::computed::ToComputedValue; impl nsTimingFunction { fn set_as_step(&mut self, function_type: nsTimingFunction_Type, steps: u32) { @@ -46,23 +47,7 @@ impl nsTimingFunction { impl From for nsTimingFunction { fn from(function: ComputedTimingFunction) -> nsTimingFunction { - let mut tf: nsTimingFunction = unsafe { mem::zeroed() }; - - match function { - ComputedTimingFunction::Steps(steps, StartEnd::Start) => { - tf.set_as_step(nsTimingFunction_Type::StepStart, steps); - }, - ComputedTimingFunction::Steps(steps, StartEnd::End) => { - tf.set_as_step(nsTimingFunction_Type::StepEnd, steps); - }, - ComputedTimingFunction::Frames(frames) => { - tf.set_as_frames(frames); - }, - ComputedTimingFunction::CubicBezier(p1, p2) => { - tf.set_as_bezier(nsTimingFunction_Type::CubicBezier, p1, p2); - }, - } - tf + SpecifiedTimingFunction::from_computed_value(&function).into() } } @@ -89,7 +74,7 @@ impl From for nsTimingFunction { Point2D::new(p2.x.get(), p2.y.get())); }, SpecifiedTimingFunction::Keyword(keyword) => { - match keyword.to_computed_value() { + match keyword.to_non_keyword_value() { ComputedTimingFunction::CubicBezier(p1, p2) => { match keyword { FunctionKeyword::Ease => { @@ -120,7 +105,10 @@ impl From for nsTimingFunction { }, ComputedTimingFunction::Frames(frames) => { tf.set_as_frames(frames) - } + }, + ComputedTimingFunction::Keyword(_) => { + panic!("Keyword function should not appear") + }, } }, } @@ -145,11 +133,21 @@ impl From for ComputedTimingFunction { ComputedTimingFunction::Frames( unsafe { function.__bindgen_anon_1.__bindgen_anon_1.as_ref().mStepsOrFrames }) } - nsTimingFunction_Type::Ease | - nsTimingFunction_Type::Linear | - nsTimingFunction_Type::EaseIn | - nsTimingFunction_Type::EaseOut | - nsTimingFunction_Type::EaseInOut | + nsTimingFunction_Type::Ease => { + ComputedTimingFunction::Keyword(FunctionKeyword::Ease) + }, + nsTimingFunction_Type::Linear => { + ComputedTimingFunction::Keyword(FunctionKeyword::Linear) + }, + nsTimingFunction_Type::EaseIn => { + ComputedTimingFunction::Keyword(FunctionKeyword::EaseIn) + }, + nsTimingFunction_Type::EaseOut => { + ComputedTimingFunction::Keyword(FunctionKeyword::EaseOut) + }, + nsTimingFunction_Type::EaseInOut => { + ComputedTimingFunction::Keyword(FunctionKeyword::EaseInOut) + }, nsTimingFunction_Type::CubicBezier => { ComputedTimingFunction::CubicBezier( TypedPoint2D::new(unsafe { function.__bindgen_anon_1.mFunc.as_ref().mX1 }, diff --git a/servo/components/style/properties/longhand/box.mako.rs b/servo/components/style/properties/longhand/box.mako.rs index c69c32fdb4f9..85350c76ddf3 100644 --- a/servo/components/style/properties/longhand/box.mako.rs +++ b/servo/components/style/properties/longhand/box.mako.rs @@ -502,6 +502,7 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto", use parser::{Parse, ParserContext}; use std::fmt; use style_traits::ToCss; + use super::FunctionKeyword; use values::specified; pub use super::parse; @@ -512,6 +513,7 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto", CubicBezier(Point2D, Point2D), Steps(u32, StartEnd), Frames(u32), + Keyword(FunctionKeyword), } impl ToCss for T { @@ -538,6 +540,9 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto", try!(frames.to_css(dest)); dest.write_str(")") }, + T::Keyword(keyword) => { + super::serialize_keyword(dest, keyword) + } } } } @@ -651,6 +656,22 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto", dest.write_str(")") } + fn serialize_keyword(dest: &mut W, keyword: FunctionKeyword) -> fmt::Result + where W: fmt::Write, + { + match keyword { + FunctionKeyword::StepStart => { + serialize_steps(dest, specified::Integer::new(1), StartEnd::Start) + }, + FunctionKeyword::StepEnd => { + serialize_steps(dest, specified::Integer::new(1), StartEnd::End) + }, + _ => { + keyword.to_css(dest) + }, + } + } + // https://drafts.csswg.org/css-transitions/#serializing-a-timing-function impl ToCss for SpecifiedValue { fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { @@ -675,17 +696,7 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto", dest.write_str(")") }, SpecifiedValue::Keyword(keyword) => { - match keyword { - FunctionKeyword::StepStart => { - serialize_steps(dest, specified::Integer::new(1), StartEnd::Start) - }, - FunctionKeyword::StepEnd => { - serialize_steps(dest, specified::Integer::new(1), StartEnd::End) - }, - _ => { - keyword.to_css(dest) - }, - } + serialize_keyword(dest, keyword) }, } } @@ -708,7 +719,9 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto", SpecifiedValue::Frames(frames) => { computed_value::T::Frames(frames.to_computed_value(context) as u32) }, - SpecifiedValue::Keyword(keyword) => keyword.to_computed_value(), + SpecifiedValue::Keyword(keyword) => { + computed_value::T::Keyword(keyword) + }, } } #[inline] @@ -729,13 +742,16 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto", let frames = frames as i32; SpecifiedValue::Frames(specified::Integer::from_computed_value(&frames)) }, + computed_value::T::Keyword(keyword) => { + SpecifiedValue::Keyword(keyword) + }, } } } impl FunctionKeyword { #[inline] - pub fn to_computed_value(&self) -> computed_value::T { + pub fn to_non_keyword_value(&self) -> computed_value::T { match *self { FunctionKeyword::Ease => ease(), FunctionKeyword::Linear => linear(), @@ -753,7 +769,7 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto", #[inline] pub fn get_initial_value() -> computed_value::T { - ease() + computed_value::T::Keyword(FunctionKeyword::Ease) } #[inline] From 7e21c8572f34cce33da77513886798f0564ef4e3 Mon Sep 17 00:00:00 2001 From: Hiroyuki Ikezoe Date: Fri, 28 Apr 2017 08:12:45 +0900 Subject: [PATCH 02/13] Bug 1358330 - Update mochitest expectations for timing-function r=xidorn MozReview-Commit-ID: 9Cm8kTx6sgT --HG-- extra : rebase_source : 8297523e4117d17e44c6d809325dfe3d61b5c4fb --- layout/style/test/stylo-failures.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/layout/style/test/stylo-failures.md b/layout/style/test/stylo-failures.md index 4db68cbc45df..67f2f2bfca9e 100644 --- a/layout/style/test/stylo-failures.md +++ b/layout/style/test/stylo-failures.md @@ -69,7 +69,6 @@ to mochitest command. * test_bug413958.html `monitorConsole` [3] * test_parser_diagnostics_unprintables.html [550] * Transition support: - * test_compute_data_with_start_struct.html `transition` [2] * test_transitions.html: pseudo elements [12] * Events: * test_animations_event_order.html [2] @@ -80,7 +79,6 @@ to mochitest command. * character not properly escaped servo/servo#15947 * test_parse_url.html [1] * test_bug829816.html [8] -* test_compute_data_with_start_struct.html `timing-function`: incorrectly computing keywords to bezier function servo/servo#15086 [2] * \@counter-style support bug 1328319 * test_counter_descriptor_storage.html [1] * test_counter_style.html [5] From f38ced1fc9c3f6b32d0f952a24719a938bb4b4a0 Mon Sep 17 00:00:00 2001 From: Andrew Swan Date: Fri, 28 Apr 2017 22:39:13 -0700 Subject: [PATCH 03/13] Bug 1354682 Add transform to XPCOMUtils.defineLazyPreferenceGetter r=kmag MozReview-Commit-ID: Lm59IHMNcy9 --HG-- extra : rebase_source : 3250d759b1b9909bcc7564139a3d7066d8376b60 --- js/xpconnect/loader/XPCOMUtils.jsm | 9 +++++++-- js/xpconnect/tests/unit/test_xpcomutils.js | 12 ++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/js/xpconnect/loader/XPCOMUtils.jsm b/js/xpconnect/loader/XPCOMUtils.jsm index 8903cbf2edb5..74cd7b89f4e0 100644 --- a/js/xpconnect/loader/XPCOMUtils.jsm +++ b/js/xpconnect/loader/XPCOMUtils.jsm @@ -299,11 +299,16 @@ this.XPCOMUtils = { * @param aOnUpdate * A function to call upon update. Receives as arguments * `(aPreference, previousValue, newValue)` + * @param aTransform + * An optional function to transform the value. If provided, + * this function receives the new preference value as an argument + * and its return value is used by the getter. */ defineLazyPreferenceGetter: function XPCU_defineLazyPreferenceGetter( aObject, aName, aPreference, aDefaultValue = null, - aOnUpdate = null) + aOnUpdate = null, + aTransform = val => val) { // Note: We need to keep a reference to this observer alive as long // as aObject is alive. This means that all of our getters need to @@ -343,7 +348,7 @@ this.XPCOMUtils = { function lazyGetter() { if (observer.value === undefined) { - observer.value = Preferences.get(aPreference, aDefaultValue); + observer.value = aTransform(Preferences.get(aPreference, aDefaultValue)); } return observer.value; } diff --git a/js/xpconnect/tests/unit/test_xpcomutils.js b/js/xpconnect/tests/unit/test_xpcomutils.js index f43454253e24..947a061ead30 100644 --- a/js/xpconnect/tests/unit/test_xpcomutils.js +++ b/js/xpconnect/tests/unit/test_xpcomutils.js @@ -151,6 +151,18 @@ add_test(function test_defineLazyPreferenceGetter() equal(obj.pref, "defaultValue", "Should return default value after pref is reset"); + obj = {}; + XPCOMUtils.defineLazyPreferenceGetter(obj, "pref", PREF, "a,b", + null, value => value.split(",")); + + deepEqual(obj.pref, ["a", "b"], "transform is applied to default value"); + + Preferences.set(PREF, "x,y,z"); + deepEqual(obj.pref, ["x", "y", "z"], "transform is applied to updated value"); + + Preferences.reset(PREF); + deepEqual(obj.pref, ["a", "b"], "transform is applied to reset default"); + run_next_test(); }); From 80536f5a455fa3acdd9d7cb80cec059b54570d08 Mon Sep 17 00:00:00 2001 From: Andrew Swan Date: Fri, 28 Apr 2017 16:11:39 -0700 Subject: [PATCH 04/13] Bug 1354682 Add legacy badges in about:addons r=mossop MozReview-Commit-ID: 3ch4lfApSIc --HG-- extra : rebase_source : d1d578e32973bcd41c2fb2f90d5dc455077b7bf4 extra : source : 9f83f42258cfe7c796fb85d8c75571279646fc41 --- .../chrome/mozapps/extensions/extensions.dtd | 4 + .../mozapps/extensions/content/extensions.css | 2 + .../mozapps/extensions/content/extensions.js | 31 +++++++ .../mozapps/extensions/content/extensions.xml | 35 +++++++ .../mozapps/extensions/content/extensions.xul | 1 + .../extensions/test/browser/browser.ini | 1 + .../extensions/test/browser/browser_legacy.js | 93 +++++++++++++++++++ .../shared/extensions/extensions.inc.css | 12 +++ 8 files changed, 179 insertions(+) create mode 100644 toolkit/mozapps/extensions/test/browser/browser_legacy.js diff --git a/toolkit/locales/en-US/chrome/mozapps/extensions/extensions.dtd b/toolkit/locales/en-US/chrome/mozapps/extensions/extensions.dtd index cca9c0e691cf..e665c6b23421 100644 --- a/toolkit/locales/en-US/chrome/mozapps/extensions/extensions.dtd +++ b/toolkit/locales/en-US/chrome/mozapps/extensions/extensions.dtd @@ -188,6 +188,10 @@ + + diff --git a/toolkit/mozapps/extensions/content/extensions.css b/toolkit/mozapps/extensions/content/extensions.css index d59fc11a5d8c..eefe5c42aaf9 100644 --- a/toolkit/mozapps/extensions/content/extensions.css +++ b/toolkit/mozapps/extensions/content/extensions.css @@ -157,12 +157,14 @@ setting[type="menulist"] { .addon[active="true"] .disabled-postfix, .addon[pending="install"] .update-postfix, .addon[pending="install"] .disabled-postfix, +.addon[legacy="false"] .legacy-warning, #detail-view:not([notification="warning"]) .warning, #detail-view:not([notification="error"]) .error, #detail-view:not([notification="info"]) .info, #detail-view:not([pending]) .pending, #detail-view:not([upgrade="true"]) .update-postfix, #detail-view[active="true"] .disabled-postfix, +#detail-view[legacy="false"] .legacy-warning, #detail-view[loading] .detail-view-container, #detail-view:not([loading]) .alert-container, .detail-row:not([value]), diff --git a/toolkit/mozapps/extensions/content/extensions.js b/toolkit/mozapps/extensions/content/extensions.js index 069fb62065b9..0bd6b7c90ab6 100644 --- a/toolkit/mozapps/extensions/content/extensions.js +++ b/toolkit/mozapps/extensions/content/extensions.js @@ -56,6 +56,7 @@ const PREF_GETADDONS_CACHE_ENABLED = "extensions.getAddons.cache.enabled"; const PREF_GETADDONS_CACHE_ID_ENABLED = "extensions.%ID%.getAddons.cache.enabled"; const PREF_UI_TYPE_HIDDEN = "extensions.ui.%TYPE%.hidden"; const PREF_UI_LASTCATEGORY = "extensions.ui.lastCategory"; +const PREF_LEGACY_EXCEPTIONS = "extensions.legacy.exceptions"; const LOADING_MSG_DELAY = 100; @@ -104,6 +105,10 @@ XPCOMUtils.defineLazyGetter(this, "gInlineOptionsStylesheets", () => { return stylesheets; }); +XPCOMUtils.defineLazyPreferenceGetter(this, "legacyWarningExceptions", + PREF_LEGACY_EXCEPTIONS, "", + raw => raw.split(",")); + document.addEventListener("load", initialize, true); window.addEventListener("unload", shutdown); @@ -3059,6 +3064,32 @@ var gDetailView = { this.node.setAttribute("type", aAddon.type); + let legacy = false; + if (!aAddon.install) { + if (aAddon.type == "extension" && !aAddon.isWebExtension) { + legacy = true; + } + if (aAddon.type == "theme") { + // The logic here is kind of clunky but we want to mark complete + // themes as legacy. There's no explicit flag for complete + // themes so explicitly check for new style themes (for which + // isWebExtension is true) or lightweight themes (which have + // ids that end with @personas.mozilla.org) + legacy = !(aAddon.isWebExtension || aAddon.id.endsWith("@personas.mozilla.org")); + } + + if (legacy && aAddon.signedStatus == AddonManager.SIGNEDSTATE_PRIVILEGED) { + legacy = false; + } + + // Exceptions that can slip through above: the default theme plus + // test pilot addons until we get SIGNEDSTATE_PRIVILEGED deployed. + if (legacy && legacyWarningExceptions.includes(aAddon.id)) { + legacy = false; + } + } + this.node.setAttribute("legacy", legacy); + // If the search category isn't selected then make sure to select the // correct category if (gCategories.selected != "addons://search/") diff --git a/toolkit/mozapps/extensions/content/extensions.xml b/toolkit/mozapps/extensions/content/extensions.xml index d91554098109..3971d40a8432 100644 --- a/toolkit/mozapps/extensions/content/extensions.xml +++ b/toolkit/mozapps/extensions/content/extensions.xml @@ -748,6 +748,38 @@ + + + + + @@ -1154,6 +1187,8 @@ else this._description.hidden = true; + this.setAttribute("legacy", this.isLegacy); + if (!("applyBackgroundUpdates" in this.mAddon) || (this.mAddon.applyBackgroundUpdates == AddonManager.AUTOUPDATE_DISABLE || (this.mAddon.applyBackgroundUpdates == AddonManager.AUTOUPDATE_DEFAULT && diff --git a/toolkit/mozapps/extensions/content/extensions.xul b/toolkit/mozapps/extensions/content/extensions.xul index 4596206b8ea2..601a22ddcfdd 100644 --- a/toolkit/mozapps/extensions/content/extensions.xul +++ b/toolkit/mozapps/extensions/content/extensions.xul @@ -567,6 +567,7 @@ align="start">