diff --git a/dom/svg/SVGContentUtils.cpp b/dom/svg/SVGContentUtils.cpp
index 7f372c9b42..21b98daba8 100644
--- a/dom/svg/SVGContentUtils.cpp
+++ b/dom/svg/SVGContentUtils.cpp
@@ -833,6 +833,14 @@ SVGContentUtils::CoordToFloat(nsSVGElement *aContent,
SVGSVGElement* ctx = aContent->GetCtx();
return ctx ? aCoord.GetPercentValue() * ctx->GetLength(SVGContentUtils::XY) : 0.0f;
}
+ case eStyleUnit_Calc: {
+ MOZ_ASSERT(aCoord.GetCalcValue(), "Invalid calc value");
+ nsStyleCoord::Calc* calc = aCoord.GetCalcValue();
+ SVGSVGElement* ctx = aContent->GetCtx();
+ float len = nsPresContext::AppUnitsToFloatCSSPixels(calc->mLength);
+ return ctx ? len + calc->mPercent * ctx->GetLength(SVGContentUtils::XY)
+ : len;
+ }
default:
return 0.0f;
}
diff --git a/layout/reftests/css-calc/reftest.list b/layout/reftests/css-calc/reftest.list
index 86fc61801e..5e04db1b38 100644
--- a/layout/reftests/css-calc/reftest.list
+++ b/layout/reftests/css-calc/reftest.list
@@ -1,2 +1,3 @@
== background-image-gradient-1.html background-image-gradient-1-ref.html
== line-height-1.html line-height-1-ref.html
+== stroke-dashoffset-1.html stroke-dashoffset-1-ref.html
diff --git a/layout/reftests/css-calc/stroke-dashoffset-1-ref.html b/layout/reftests/css-calc/stroke-dashoffset-1-ref.html
new file mode 100644
index 0000000000..037bb9263b
--- /dev/null
+++ b/layout/reftests/css-calc/stroke-dashoffset-1-ref.html
@@ -0,0 +1,63 @@
+
+
+
diff --git a/layout/reftests/css-calc/stroke-dashoffset-1.html b/layout/reftests/css-calc/stroke-dashoffset-1.html
new file mode 100644
index 0000000000..4cee290041
--- /dev/null
+++ b/layout/reftests/css-calc/stroke-dashoffset-1.html
@@ -0,0 +1,63 @@
+
+
+
diff --git a/layout/style/StyleAnimationValue.cpp b/layout/style/StyleAnimationValue.cpp
index ff67835536..2332de6a6a 100644
--- a/layout/style/StyleAnimationValue.cpp
+++ b/layout/style/StyleAnimationValue.cpp
@@ -63,11 +63,15 @@ GetCommonUnit(nsCSSPropertyID aProperty,
StyleAnimationValue::Unit aSecondUnit)
{
if (aFirstUnit != aSecondUnit) {
+ bool numberAsPixel =
+ nsCSSProps::PropHasFlags(aProperty, CSS_PROPERTY_NUMBERS_ARE_PIXELS);
if (nsCSSProps::PropHasFlags(aProperty, CSS_PROPERTY_STORES_CALC) &&
- (aFirstUnit == StyleAnimationValue::eUnit_Coord ||
+ ((aFirstUnit == StyleAnimationValue::eUnit_Float && numberAsPixel) ||
+ aFirstUnit == StyleAnimationValue::eUnit_Coord ||
aFirstUnit == StyleAnimationValue::eUnit_Percent ||
aFirstUnit == StyleAnimationValue::eUnit_Calc) &&
- (aSecondUnit == StyleAnimationValue::eUnit_Coord ||
+ ((aSecondUnit == StyleAnimationValue::eUnit_Float && numberAsPixel) ||
+ aSecondUnit == StyleAnimationValue::eUnit_Coord ||
aSecondUnit == StyleAnimationValue::eUnit_Percent ||
aSecondUnit == StyleAnimationValue::eUnit_Calc)) {
// We can use calc() as the common unit.
@@ -354,6 +358,12 @@ ExtractCalcValue(const StyleAnimationValue& aValue)
result.mHasPercent = true;
return result;
}
+ if (aValue.GetUnit() == StyleAnimationValue::eUnit_Float) {
+ result.mLength = aValue.GetFloatValue();
+ result.mPercent = 0.0f;
+ result.mHasPercent = false;
+ return result;
+ }
MOZ_ASSERT(aValue.GetUnit() == StyleAnimationValue::eUnit_Calc,
"unexpected unit");
nsCSSValue *val = aValue.GetCSSValueValue();
diff --git a/layout/style/nsCSSPropList.h b/layout/style/nsCSSPropList.h
index e78dafcc5c..45e919d4f8 100644
--- a/layout/style/nsCSSPropList.h
+++ b/layout/style/nsCSSPropList.h
@@ -3814,9 +3814,10 @@ CSS_PROP_SVG(
stroke_dashoffset,
StrokeDashoffset,
CSS_PROPERTY_PARSE_VALUE |
- CSS_PROPERTY_NUMBERS_ARE_PIXELS,
+ CSS_PROPERTY_NUMBERS_ARE_PIXELS |
+ CSS_PROPERTY_STORES_CALC,
"",
- VARIANT_HLPN | VARIANT_OPENTYPE_SVG_KEYWORD,
+ VARIANT_HLPN | VARIANT_OPENTYPE_SVG_KEYWORD | VARIANT_CALC,
kStrokeContextValueKTable,
offsetof(nsStyleSVG, mStrokeDashoffset),
eStyleAnimType_Coord)
diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp
index 04715aa99a..74ba732885 100644
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -4492,6 +4492,15 @@ struct LengthNumberCalcObj
bool mIsNumber;
};
+struct RealNumberComputedCalc
+{
+ // We use float for mLength, so it can support real numbers.
+ float mLength = 0.0f;
+ float mPercent = 0.0f;
+ bool mIsNumber = false;
+};
+
+
struct LengthNumberCalcOps : public css::NumbersAlreadyNormalizedOps
{
typedef LengthNumberCalcObj result_type;
@@ -4574,6 +4583,96 @@ struct LengthNumberCalcOps : public css::NumbersAlreadyNormalizedOps
}
};
+// This is like LengthNumberCalcOps, but then for real/float.
+struct LengthPercentNumberCalcOps : public css::NumbersAlreadyNormalizedOps
+{
+ typedef RealNumberComputedCalc result_type;
+
+ nsStyleContext* const mContext;
+ nsPresContext* const mPresContext;
+ RuleNodeCacheConditions& mConditions;
+ bool mHasPercent = false;
+
+ LengthPercentNumberCalcOps(nsStyleContext* aContext,
+ nsPresContext* aPresContext,
+ RuleNodeCacheConditions& aConditions)
+ : mContext(aContext),
+ mPresContext(aPresContext),
+ mConditions(aConditions) { }
+
+ result_type
+ MergeAdditive(nsCSSUnit aCalcFunction,
+ result_type aValue1, result_type aValue2)
+ {
+ MOZ_ASSERT(aValue1.mIsNumber == aValue2.mIsNumber);
+ MOZ_ASSERT(aCalcFunction == eCSSUnit_Calc_Plus ||
+ aCalcFunction == eCSSUnit_Calc_Minus,
+ "unexpected unit");
+
+ result_type result;
+ result.mIsNumber = aValue1.mIsNumber;
+ if (aCalcFunction == eCSSUnit_Calc_Plus) {
+ result.mLength = aValue1.mLength + aValue2.mLength;
+ result.mPercent = aValue1.mPercent + aValue2.mPercent;
+ } else {
+ result.mLength = aValue2.mLength == NS_IEEEPositiveInfinity() ?
+ 0.0f :
+ aValue1.mLength - aValue2.mLength;
+ result.mPercent = aValue1.mPercent - aValue2.mPercent;
+ }
+ return result;
+ }
+
+ result_type
+ MergeMultiplicativeL(nsCSSUnit aCalcFunction,
+ float aValue1, result_type aValue2)
+ {
+ MOZ_ASSERT(aCalcFunction == eCSSUnit_Calc_Times_L,
+ "unexpected unit");
+ result_type result;
+ result.mLength = aValue1 * aValue2.mLength;
+ result.mPercent = aValue1 * aValue2.mPercent;
+ result.mIsNumber = aValue2.mIsNumber;
+ return result;
+ }
+
+ result_type
+ MergeMultiplicativeR(nsCSSUnit aCalcFunction,
+ result_type aValue1, float aValue2)
+ {
+ MOZ_ASSERT(aCalcFunction == eCSSUnit_Calc_TimesR ||
+ aCalcFunction == eCSSUnit_Divided,
+ "unexpected unit");
+ result_type result;
+ if (aCalcFunction == eCSSUnit_Calc_Divided) {
+ aValue2 = 1.0f / aValue2;
+ }
+ result.mLength = aValue1.mLength * aValue2;
+ result.mPercent = aValue1.mPercent * aValue2;
+ result.mIsNumber = aValue1.mIsNumber;
+ return result;
+ }
+
+ result_type
+ ComputeLeafValue(const nsCSSValue& aValue)
+ {
+ result_type result;
+ if (aValue.IsLengthUnit()) {
+ result.mLength = CalcLength(aValue, mContext, mPresContext, mConditions);
+ } else if (aValue.GetUnit() == eCSSUnit_Percent) {
+ result.mPercent = aValue.GetPercentValue();
+ mHasPercent = true;
+ } else if (aValue.GetUnit() == eCSSUnit_Number) {
+ result.mLength = aValue.GetFloatValue();
+ result.mIsNumber = true;
+ } else {
+ MOZ_ASSERT_UNREACHABLE("unexpected unit");
+ result.mLength = CalcLength(aValue, mContext, mPresContext, mConditions);
+ }
+ return result;
+ }
+};
+
struct SetLineHeightCalcOps : public LengthNumberCalcOps
{
SetLineHeightCalcOps(nsStyleContext* aStyleContext,
@@ -9626,6 +9725,18 @@ nsRuleNode::ComputeSVGData(void* aStartStruct,
strokeDashoffsetValue->GetIntValue() == NS_STYLE_STROKE_PROP_CONTEXT_VALUE);
if (svg->StrokeDashoffsetFromObject()) {
svg->mStrokeDashoffset.SetCoordValue(0);
+ } else if (strokeDashoffsetValue->IsCalcUnit()) {
+ LengthPercentNumberCalcOps ops(aContext, mPresContext, conditions);
+ RealNumberComputedCalc obj = css::ComputeCalc(*strokeDashoffsetValue, ops);
+ if (obj.mIsNumber) {
+ svg->mStrokeDashoffset.SetFactorValue(obj.mLength);
+ } else {
+ nsStyleCoord::Calc* calcObj = new nsStyleCoord::Calc;
+ calcObj->mLength = NSToCoordRoundWithClamp(obj.mLength);
+ calcObj->mPercent = obj.mPercent;
+ calcObj->mHasPercent = ops.mHasPercent;
+ svg->mStrokeDashoffset.SetCalcValue(calcObj);
+ }
} else {
SetCoord(*aRuleData->ValueForStrokeDashoffset(),
svg->mStrokeDashoffset, parentSVG->mStrokeDashoffset,
diff --git a/toolkit/themes/windows/global/toolbar.css b/toolkit/themes/windows/global/toolbar.css
index 38c8a617a5..97310e1aeb 100644
--- a/toolkit/themes/windows/global/toolbar.css
+++ b/toolkit/themes/windows/global/toolbar.css
@@ -17,6 +17,15 @@ toolbox {
-moz-border-top-colors: ThreeDShadow ThreeDHighlight;
}
+@media (-moz-os-version: windows-win10) and (-moz-windows-theme: aero) {
+ toolbox {
+ /* Windows 10's "aero" msstyle sourced toolbox background is pure white
+ so don't use the widget toolbox styling and fallback to -moz-Dialog's
+ color which by default should be a non-blinding rgb(240, 240, 240) */
+ -moz-appearance: none;
+ }
+}
+
/* ::::: toolbar & menubar ::::: */
toolbar, menubar {