Bug 1055285 part 2: Implement CSS parsing & computation (but not animation) for 'object-position' property. r=heycam

This commit is contained in:
Daniel Holbert 2014-09-09 18:09:32 -07:00
parent cabdaabbb4
commit c6d3b18b7d
9 changed files with 109 additions and 3 deletions

View File

@ -781,6 +781,7 @@ protected:
bool ParseMargin();
bool ParseMarks(nsCSSValue& aValue);
bool ParseTransform(bool aIsPrefixed);
bool ParseObjectPosition();
bool ParseOutline();
bool ParseOverflow();
bool ParsePadding();
@ -9788,6 +9789,8 @@ CSSParserImpl::ParsePropertyByFunction(nsCSSProperty aPropID)
case eCSSProperty_margin_start:
return ParseDirectionalBoxProperty(eCSSProperty_margin_start,
NS_BOXPROP_SOURCE_LOGICAL);
case eCSSProperty_object_position:
return ParseObjectPosition();
case eCSSProperty_outline:
return ParseOutline();
case eCSSProperty_overflow:
@ -12892,6 +12895,18 @@ CSSParserImpl::ParseMarks(nsCSSValue& aValue)
return false;
}
bool
CSSParserImpl::ParseObjectPosition()
{
nsCSSValue value;
if (!ParseVariant(value, VARIANT_INHERIT, nullptr) &&
!ParsePositionValue(value)) {
return false;
}
AppendValue(eCSSProperty_object_position, value);
return true;
}
bool
CSSParserImpl::ParseOutline()
{

View File

@ -2531,6 +2531,17 @@ CSS_PROP_POSITION(
kObjectFitKTable,
CSS_PROP_NO_OFFSET,
eStyleAnimType_None)
CSS_PROP_POSITION(
object-position,
object_position,
ObjectPosition,
CSS_PROPERTY_PARSE_FUNCTION |
CSS_PROPERTY_STORES_CALC,
"layout.css.object-fit-and-position.enabled",
0,
kBackgroundPositionKTable,
CSS_PROP_NO_OFFSET,
eStyleAnimType_None) // XXXdholbert Use "_Custom", and implement animation
CSS_PROP_DISPLAY(
opacity,
opacity,

View File

@ -4196,6 +4196,14 @@ nsComputedDOMStyle::DoGetObjectFit()
return val;
}
CSSValue*
nsComputedDOMStyle::DoGetObjectPosition()
{
nsDOMCSSValueList* valueList = GetROCSSValueList(false);
SetValueToPosition(StylePosition()->mObjectPosition, valueList);
return valueList;
}
CSSValue*
nsComputedDOMStyle::DoGetLeft()
{

View File

@ -236,6 +236,7 @@ private:
mozilla::dom::CSSValue* DoGetMinWidth();
mozilla::dom::CSSValue* DoGetMixBlendMode();
mozilla::dom::CSSValue* DoGetObjectFit();
mozilla::dom::CSSValue* DoGetObjectPosition();
mozilla::dom::CSSValue* DoGetLeft();
mozilla::dom::CSSValue* DoGetTop();
mozilla::dom::CSSValue* DoGetRight();

View File

@ -167,6 +167,7 @@ COMPUTED_STYLE_PROP(min_height, MinHeight)
COMPUTED_STYLE_PROP(min_width, MinWidth)
COMPUTED_STYLE_PROP(mix_blend_mode, MixBlendMode)
COMPUTED_STYLE_PROP(object_fit, ObjectFit)
COMPUTED_STYLE_PROP(object_position, ObjectPosition)
COMPUTED_STYLE_PROP(opacity, Opacity)
// COMPUTED_STYLE_PROP(orphans, Orphans)
//// COMPUTED_STYLE_PROP(outline, Outline)

View File

@ -7666,6 +7666,24 @@ nsRuleNode::ComputePositionData(void* aStartStruct,
parentPos->mObjectFit,
NS_STYLE_OBJECT_FIT_FILL, 0, 0, 0, 0);
// object-position
const nsCSSValue& objectPosition = *aRuleData->ValueForObjectPosition();
switch (objectPosition.GetUnit()) {
case eCSSUnit_Null:
break;
case eCSSUnit_Inherit:
canStoreInRuleTree = false;
pos->mObjectPosition = parentPos->mObjectPosition;
break;
case eCSSUnit_Initial:
case eCSSUnit_Unset:
pos->mObjectPosition.SetInitialPercentValues(0.5f);
break;
default:
ComputePositionValue(aContext, objectPosition,
pos->mObjectPosition, canStoreInRuleTree);
}
// grid-auto-flow
const nsCSSValue& gridAutoFlow = *aRuleData->ValueForGridAutoFlow();
switch (gridAutoFlow.GetUnit()) {

View File

@ -1266,7 +1266,11 @@ bool nsStyleSVGPaint::operator==(const nsStyleSVGPaint& aOther) const
nsStylePosition::nsStylePosition(void)
{
MOZ_COUNT_CTOR(nsStylePosition);
// positioning values not inherited
mObjectPosition.SetInitialPercentValues(0.5f);
nsStyleCoord autoCoord(eStyleUnit_Auto);
mOffset.SetLeft(autoCoord);
mOffset.SetTop(autoCoord);
@ -1317,7 +1321,8 @@ nsStylePosition::~nsStylePosition(void)
}
nsStylePosition::nsStylePosition(const nsStylePosition& aSource)
: mOffset(aSource.mOffset)
: mObjectPosition(aSource.mObjectPosition)
, mOffset(aSource.mOffset)
, mWidth(aSource.mWidth)
, mMinWidth(aSource.mMinWidth)
, mMaxWidth(aSource.mMaxWidth)
@ -1369,9 +1374,10 @@ nsChangeHint nsStylePosition::CalcDifference(const nsStylePosition& aOther) cons
{
nsChangeHint hint = nsChangeHint(0);
// Changes to "z-index" & "object-fit" require a repaint.
// Changes to "z-index", "object-fit", & "object-position" require a repaint.
if (mZIndex != aOther.mZIndex ||
mObjectFit != aOther.mObjectFit) {
mObjectFit != aOther.mObjectFit ||
mObjectPosition != aOther.mObjectPosition) {
NS_UpdateHint(hint, nsChangeHint_RepaintFrame);
}

View File

@ -1333,6 +1333,11 @@ struct nsStylePosition {
return nsChangeHint(0);
}
// XXXdholbert nsStyleBackground::Position should probably be moved to a
// different scope, since we're now using it in multiple style structs.
typedef nsStyleBackground::Position Position;
Position mObjectPosition; // [reset]
nsStyleSides mOffset; // [reset] coord, percent, calc, auto
nsStyleCoord mWidth; // [reset] coord, percent, enum, calc, auto
nsStyleCoord mMinWidth; // [reset] coord, percent, enum, calc

View File

@ -5381,6 +5381,47 @@ if (SpecialPowers.getBoolPref("layout.css.object-fit-and-position.enabled")) {
other_values: [ "contain", "cover", "none", "scale-down" ],
invalid_values: [ "auto", "5px", "100%" ]
};
gCSSProperties["object-position"] = {
domProp: "objectPosition",
inherited: false,
type: CSS_TYPE_LONGHAND,
initial_values: [ "50% 50%", "50%", "center", "center center" ],
other_values: [
"calc(20px)",
"calc(20px) 10px",
"10px calc(20px)",
"calc(20px) 25%",
"25% calc(20px)",
"calc(20px) calc(20px)",
"calc(20px + 1em) calc(20px / 2)",
"calc(20px + 50%) calc(50% - 10px)",
"calc(-20px) calc(-50%)",
"calc(-20%) calc(-50%)",
"0px 0px",
"right 20px top 60px",
"right 20px bottom 60px",
"left 20px top 60px",
"left 20px bottom 60px",
"right -50px top -50px",
"left -50px bottom -50px",
"right 20px top -50px",
"right -20px top 50px",
"right 3em bottom 10px",
"bottom 3em right 10px",
"top 3em right 10px",
"left 15px",
"10px top",
"left top 15px",
"left 10px top",
"left 20%",
"right 20%"
],
invalid_values: [ "center 10px center 4px", "center 10px center",
"top 20%", "bottom 20%", "50% left", "top 50%",
"50% bottom 10%", "right 10% 50%", "left right",
"top bottom", "left 10% right",
"top 20px bottom 20px", "left left", "20 20" ]
};
}
if (SpecialPowers.getBoolPref("layout.css.overflow-clip-box.enabled")) {