Allow calc() as an intermediate common animation unit between lengths, percentages, and calc(). (Bug 520234) r=bzbarsky a=blocking2.0:beta7

This commit is contained in:
L. David Baron 2010-09-15 08:11:26 -07:00
Родитель 5b3f530df7
Коммит 5d09552b98
2 изменённых файлов: 130 добавлений и 29 удалений

Просмотреть файл

@ -73,14 +73,21 @@ namespace css = mozilla::css;
*/
static
nsStyleAnimation::Unit
GetCommonUnit(nsStyleAnimation::Unit aFirstUnit,
GetCommonUnit(nsCSSProperty aProperty,
nsStyleAnimation::Unit aFirstUnit,
nsStyleAnimation::Unit aSecondUnit)
{
// XXXdholbert Naive implementation for now: simply require that the input
// units match.
if (aFirstUnit != aSecondUnit) {
// NOTE: Some unit-pairings will need special handling,
// e.g. percent vs coord (bug 520234)
if (nsCSSProps::PropHasFlags(aProperty, CSS_PROPERTY_STORES_CALC) &&
(aFirstUnit == nsStyleAnimation::eUnit_Coord ||
aFirstUnit == nsStyleAnimation::eUnit_Percent ||
aFirstUnit == nsStyleAnimation::eUnit_Calc) &&
(aSecondUnit == nsStyleAnimation::eUnit_Coord ||
aSecondUnit == nsStyleAnimation::eUnit_Percent ||
aSecondUnit == nsStyleAnimation::eUnit_Calc)) {
// We can use calc() as the common unit.
return nsStyleAnimation::eUnit_Calc;
}
return nsStyleAnimation::eUnit_Null;
}
return aFirstUnit;
@ -129,13 +136,26 @@ struct CalcValue {
static CalcValue
ExtractCalcValue(const nsStyleAnimation::Value& aValue)
{
CalcValue result;
if (aValue.GetUnit() == nsStyleAnimation::eUnit_Coord) {
result.mLength =
nsPresContext::AppUnitsToFloatCSSPixels(aValue.GetCoordValue());
result.mPercent = 0.0f;
result.mHasPercent = PR_FALSE;
return result;
}
if (aValue.GetUnit() == nsStyleAnimation::eUnit_Percent) {
result.mLength = 0.0f;
result.mPercent = aValue.GetPercentValue();
result.mHasPercent = PR_TRUE;
return result;
}
NS_ABORT_IF_FALSE(aValue.GetUnit() == nsStyleAnimation::eUnit_Calc,
"unexpected unit");
nsCSSValue *val = aValue.GetCSSValueValue();
NS_ABORT_IF_FALSE(val->GetUnit() == eCSSUnit_Calc, "unexpected unit");
nsCSSValue::Array *arr = val->GetArrayValue();
NS_ABORT_IF_FALSE(arr->Count() == 1, "unexpected length");
CalcValue result;
const nsCSSValue &topval = arr->Item(0);
if (topval.GetUnit() == eCSSUnit_Pixel) {
@ -188,7 +208,8 @@ nsStyleAnimation::ComputeDistance(nsCSSProperty aProperty,
const Value& aEndValue,
double& aDistance)
{
Unit commonUnit = GetCommonUnit(aStartValue.GetUnit(), aEndValue.GetUnit());
Unit commonUnit =
GetCommonUnit(aProperty, aStartValue.GetUnit(), aEndValue.GetUnit());
switch (commonUnit) {
case eUnit_Null:
@ -1232,7 +1253,8 @@ nsStyleAnimation::AddWeighted(nsCSSProperty aProperty,
double aCoeff2, const Value& aValue2,
Value& aResultValue)
{
Unit commonUnit = GetCommonUnit(aValue1.GetUnit(), aValue2.GetUnit());
Unit commonUnit =
GetCommonUnit(aProperty, aValue1.GetUnit(), aValue2.GetUnit());
// Maybe need a followup method to convert the inputs into the common
// unit-type, if they don't already match it. (Or would it make sense to do
// that in GetCommonUnit? in which case maybe ConvertToCommonUnit would be

Просмотреть файл

@ -87,55 +87,82 @@ var supported_properties = {
"border-top-color": [ test_color_transition,
test_border_color_transition ],
"border-top-width": [ test_length_transition ],
"bottom": [ test_length_transition, test_percent_transition ],
"bottom": [ test_length_transition, test_percent_transition,
test_length_percent_calc_transition ],
"clip": [ test_rect_transition ],
"color": [ test_color_transition ],
"fill": [ test_color_transition ],
"fill-opacity" : [ test_float_zeroToOne_transition ],
"flood-color": [ test_color_transition ],
"flood-opacity" : [ test_float_zeroToOne_transition ],
"font-size": [ test_length_transition, test_percent_transition ],
"font-size": [ test_length_transition, test_percent_transition,
test_length_percent_calc_transition ],
"font-size-adjust": [ test_float_zeroToOne_transition,
test_float_aboveOne_transition ],
"font-stretch": [ test_font_stretch ],
"font-weight": [ test_font_weight ],
"height": [ test_length_transition, test_percent_transition ],
"left": [ test_length_transition, test_percent_transition ],
"height": [ test_length_transition, test_percent_transition,
test_length_percent_calc_transition ],
"left": [ test_length_transition, test_percent_transition,
test_length_percent_calc_transition ],
"letter-spacing": [ test_length_transition ],
"lighting-color": [ test_color_transition ],
// NOTE: when calc() is supported on 'line-height', we should add
// test_length_percent_calc_transition.
"line-height": [ test_length_transition, test_percent_transition ],
"margin-bottom": [ test_length_transition, test_percent_transition ],
"margin-left": [ test_length_transition, test_percent_transition ],
"margin-right": [ test_length_transition, test_percent_transition ],
"margin-top": [ test_length_transition, test_percent_transition ],
"margin-bottom": [ test_length_transition, test_percent_transition,
test_length_percent_calc_transition ],
"margin-left": [ test_length_transition, test_percent_transition,
test_length_percent_calc_transition ],
"margin-right": [ test_length_transition, test_percent_transition,
test_length_percent_calc_transition ],
"margin-top": [ test_length_transition, test_percent_transition,
test_length_percent_calc_transition ],
"marker-offset": [ test_length_transition ],
"max-height": [ test_length_transition, test_percent_transition ],
"max-width": [ test_length_transition, test_percent_transition ],
"min-height": [ test_length_transition, test_percent_transition ],
"min-width": [ test_length_transition, test_percent_transition ],
"max-height": [ test_length_transition, test_percent_transition,
test_length_percent_calc_transition ],
"max-width": [ test_length_transition, test_percent_transition,
test_length_percent_calc_transition ],
"min-height": [ test_length_transition, test_percent_transition,
test_length_percent_calc_transition ],
"min-width": [ test_length_transition, test_percent_transition,
test_length_percent_calc_transition ],
"opacity" : [ test_float_zeroToOne_transition ],
"outline-color": [ test_color_transition ],
"outline-offset": [ test_length_transition ],
"outline-width": [ test_length_transition ],
"padding-bottom": [ test_length_transition, test_percent_transition ],
"padding-left": [ test_length_transition, test_percent_transition ],
"padding-right": [ test_length_transition, test_percent_transition ],
"padding-top": [ test_length_transition, test_percent_transition ],
"right": [ test_length_transition, test_percent_transition ],
"padding-bottom": [ test_length_transition, test_percent_transition,
test_length_percent_calc_transition ],
"padding-left": [ test_length_transition, test_percent_transition,
test_length_percent_calc_transition ],
"padding-right": [ test_length_transition, test_percent_transition,
test_length_percent_calc_transition ],
"padding-top": [ test_length_transition, test_percent_transition,
test_length_percent_calc_transition ],
"right": [ test_length_transition, test_percent_transition,
test_length_percent_calc_transition ],
"stop-color": [ test_color_transition ],
"stop-opacity" : [ test_float_zeroToOne_transition ],
"stroke": [ test_color_transition ],
"stroke-dasharray": [ test_dasharray_transition ],
// NOTE: when calc() is supported on 'stroke-dashoffset', we should
// add test_length_percent_calc_transition.
"stroke-dashoffset": [ test_length_transition, test_percent_transition ],
"stroke-miterlimit": [ test_float_aboveOne_transition ],
"stroke-opacity" : [ test_float_zeroToOne_transition ],
// NOTE: when calc() is supported on 'stroke-width', we should add
// test_length_percent_calc_transition.
"stroke-width": [ test_length_transition, test_percent_transition ],
"text-indent": [ test_length_transition, test_percent_transition ],
"text-indent": [ test_length_transition, test_percent_transition,
test_length_percent_calc_transition ],
"text-shadow": [ test_shadow_transition ],
"top": [ test_length_transition, test_percent_transition ],
"vertical-align": [ test_length_transition, test_percent_transition ],
"top": [ test_length_transition, test_percent_transition,
test_length_percent_calc_transition ],
"vertical-align": [ test_length_transition, test_percent_transition,
test_length_percent_calc_transition ],
"visibility": [ test_visibility_transition ],
"width": [ test_length_transition, test_percent_transition ],
"width": [ test_length_transition, test_percent_transition,
test_length_percent_calc_transition ],
"word-spacing": [ test_length_transition ],
"z-index": [ test_zindex_transition, test_pos_integer_or_auto_transition ],
};
@ -302,6 +329,58 @@ function test_percent_transition(prop) {
"percent-valued property " + prop + ": percent computes to number");
}
function test_length_percent_calc_transition(prop) {
div.style.setProperty("-moz-transition-property", "none", "");
div.style.setProperty(prop, "0%", "");
var av = cs.getPropertyValue(prop);
var a = any_unit_to_num(av);
div.style.setProperty(prop, "100%", "");
var bv = cs.getPropertyValue(prop);
var b = any_unit_to_num(bv);
div.style.setProperty(prop, "100px", "");
var cv = cs.getPropertyValue(prop);
var c = any_unit_to_num(cv);
isnot(b, a, "different percentages (" + av + " and " + bv +
") should be different for " + prop);
div.style.setProperty(prop, "50%", "");
var v1v = cs.getPropertyValue(prop);
is(any_unit_to_num(v1v) * 2, a + b,
"computed value before transition for " + prop + ": '" +
v1v + "' should be halfway " +
"between '" + av + "' + and '" + bv + "'.");
div.style.setProperty("-moz-transition-property", prop, "");
div.style.setProperty(prop, "200px", "");
var v2v = cs.getPropertyValue(prop);
is(any_unit_to_num(v2v) * 8, 5*a + 3*b + 4*c,
"interpolation between length and percent for " + prop + ": '"
+ v2v + "'");
div.style.setProperty("-moz-transition-property", "none", "");
div.style.setProperty(prop, "-moz-calc(100% + 200px)", "");
v1v = cs.getPropertyValue(prop);
is(any_unit_to_num(v1v), b + 2*c,
"computed value before transition for " + prop + ": '" + v1v + "'");
div.style.setProperty("-moz-transition-property", prop, "");
div.style.setProperty(prop, "300%", "");
v2v = cs.getPropertyValue(prop);
is(any_unit_to_num(v2v) * 2, -1*a + 3*b + 3*c,
"interpolation between calc() and percent for " + prop + ": '" +
v2v + "'");
div.style.setProperty("-moz-transition-property", "none", "");
div.style.setProperty(prop, "400px", "");
v1v = cs.getPropertyValue(prop);
is(any_unit_to_num(v1v), 4*c,
"computed value before transition for " + prop + ": '" + v1v + "'");
div.style.setProperty("-moz-transition-property", prop, "");
div.style.setProperty(prop, "-moz-calc(200% + 200px)", "");
v2v = cs.getPropertyValue(prop);
is(any_unit_to_num(v2v) * 2, a + b + 7*c,
"interpolation between length and calc() for " + prop + ": '" +
v2v + "'");
}
function test_color_transition(prop) {
div.style.setProperty("-moz-transition-property", "none", "");
div.style.setProperty(prop, "rgb(255, 28, 0)", "");