Bug 1176782 part 2 - [css-align] Implement the 'justify-self' property in the style system. r=SimonSapin

This commit is contained in:
Mats Palmgren 2015-11-03 15:18:05 +01:00
parent cb1d1d16b1
commit 9ef57353d7
10 changed files with 159 additions and 2 deletions

View File

@ -939,6 +939,7 @@ protected:
bool ParseAlignJustifyPosition(nsCSSValue& aResult,
const KTableValue aTable[]);
bool ParseJustifyItems();
bool ParseJustifySelf();
// for 'clip' and '-moz-image-region'
bool ParseRect(nsCSSProperty aPropID);
@ -9448,6 +9449,24 @@ CSSParserImpl::ParseJustifyItems()
return true;
}
// auto | stretch | <baseline-position> |
// [ <overflow-position>? && <self-position> ]
bool
CSSParserImpl::ParseJustifySelf()
{
nsCSSValue value;
if (!ParseSingleTokenVariant(value, VARIANT_INHERIT, nullptr)) {
if (!ParseEnum(value, nsCSSProps::kAlignAutoStretchBaseline)) {
if (!ParseAlignJustifyPosition(value, nsCSSProps::kAlignSelfPosition) ||
value.GetUnit() == eCSSUnit_Null) {
return false;
}
}
}
AppendValue(eCSSProperty_justify_self, value);
return true;
}
// <color-stop> : <color> [ <percentage> | <length> ]?
bool
CSSParserImpl::ParseColorStop(nsCSSValueGradient* aGradient)
@ -10573,6 +10592,8 @@ CSSParserImpl::ParsePropertyByFunction(nsCSSProperty aPropID)
return ParseRect(eCSSProperty_image_region);
case eCSSProperty_justify_items:
return ParseJustifyItems();
case eCSSProperty_justify_self:
return ParseJustifySelf();
case eCSSProperty_list_style:
return ParseListStyle();
case eCSSProperty_margin:

View File

@ -1717,6 +1717,16 @@ CSS_PROP_POSITION(
nullptr,
CSS_PROP_NO_OFFSET,
eStyleAnimType_None)
CSS_PROP_POSITION(
justify-self,
justify_self,
JustifySelf,
CSS_PROPERTY_PARSE_FUNCTION,
"",
0,
nullptr,
CSS_PROP_NO_OFFSET,
eStyleAnimType_None)
CSS_PROP_DISPLAY(
float,
float,

View File

@ -1318,6 +1318,7 @@ nsCSSValue::AppendToString(nsCSSProperty aProperty, nsAString& aResult,
break;
case eCSSProperty_justify_items:
case eCSSProperty_justify_self:
AppendAlignJustifyValueToString(intValue, aResult);
break;

View File

@ -3993,6 +3993,18 @@ nsComputedDOMStyle::DoGetJustifyItems()
return val;
}
CSSValue*
nsComputedDOMStyle::DoGetJustifySelf()
{
nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue;
nsAutoString str;
auto justify = StylePosition()->
ComputedJustifySelf(StyleDisplay(), mStyleContext->GetParent());
nsCSSValue::AppendAlignJustifyValueToString(justify, str);
val->SetString(str);
return val;
}
CSSValue*
nsComputedDOMStyle::DoGetFloatEdge()
{

View File

@ -484,6 +484,7 @@ private:
mozilla::dom::CSSValue* DoGetAlignSelf();
mozilla::dom::CSSValue* DoGetJustifyContent();
mozilla::dom::CSSValue* DoGetJustifyItems();
mozilla::dom::CSSValue* DoGetJustifySelf();
/* SVG properties */
mozilla::dom::CSSValue* DoGetFill();

View File

@ -151,6 +151,7 @@ COMPUTED_STYLE_PROP(ime_mode, IMEMode)
COMPUTED_STYLE_PROP(isolation, Isolation)
COMPUTED_STYLE_PROP(justify_content, JustifyContent)
COMPUTED_STYLE_PROP(justify_items, JustifyItems)
COMPUTED_STYLE_PROP(justify_self, JustifySelf)
COMPUTED_STYLE_PROP(left, Left)
COMPUTED_STYLE_PROP(letter_spacing, LetterSpacing)
COMPUTED_STYLE_PROP(line_height, LineHeight)

View File

@ -7878,6 +7878,29 @@ nsRuleNode::ComputePositionData(void* aStartStruct,
NS_STYLE_JUSTIFY_AUTO, 0, 0, 0, 0);
}
// justify-self: enum, inherit, initial
const auto& justifySelfValue = *aRuleData->ValueForJustifySelf();
if (MOZ_UNLIKELY(justifySelfValue.GetUnit() == eCSSUnit_Inherit)) {
if (MOZ_LIKELY(parentContext)) {
nsStyleContext* grandparentContext = parentContext->GetParent();
if (MOZ_LIKELY(grandparentContext)) {
aContext->AddStyleBit(NS_STYLE_USES_GRANDANCESTOR_STYLE);
}
pos->mJustifySelf =
parentPos->ComputedJustifySelf(parentContext->StyleDisplay(),
grandparentContext);
} else {
pos->mJustifySelf = NS_STYLE_JUSTIFY_START;
}
conditions.SetUncacheable();
} else {
SetDiscrete(justifySelfValue,
pos->mJustifySelf, conditions,
SETDSC_ENUMERATED | SETDSC_UNSET_INITIAL,
parentPos->mJustifySelf, // not used, we handle 'inherit' above
NS_STYLE_JUSTIFY_AUTO, 0, 0, 0, 0);
}
// flex-basis: auto, length, percent, enum, calc, inherit, initial
// (Note: The flags here should match those used for 'width' property above.)
SetCoord(*aRuleData->ValueForFlexBasis(), pos->mFlexBasis, parentPos->mFlexBasis,

View File

@ -1435,6 +1435,7 @@ nsStylePosition::nsStylePosition(void)
mAlignItems = NS_STYLE_ALIGN_ITEMS_INITIAL_VALUE;
mAlignSelf = NS_STYLE_ALIGN_SELF_AUTO;
mJustifyItems = NS_STYLE_JUSTIFY_AUTO;
mJustifySelf = NS_STYLE_JUSTIFY_AUTO;
mFlexDirection = NS_STYLE_FLEX_DIRECTION_ROW;
mFlexWrap = NS_STYLE_FLEX_WRAP_NOWRAP;
mJustifyContent = NS_STYLE_JUSTIFY_CONTENT_FLEX_START;
@ -1475,6 +1476,7 @@ nsStylePosition::nsStylePosition(const nsStylePosition& aSource)
, mAlignItems(aSource.mAlignItems)
, mAlignSelf(aSource.mAlignSelf)
, mJustifyItems(aSource.mJustifyItems)
, mJustifySelf(aSource.mJustifySelf)
, mFlexDirection(aSource.mFlexDirection)
, mFlexWrap(aSource.mFlexWrap)
, mJustifyContent(aSource.mJustifyContent)
@ -1587,10 +1589,11 @@ nsStylePosition::CalcDifference(const nsStylePosition& aOther,
return NS_CombineHint(hint, nsChangeHint_AllReflowHints);
}
// Changing 'justify-content/items' might affect the positioning,
// Changing 'justify-content/items/self' might affect the positioning,
// but it won't affect any sizing.
if (mJustifyContent != aOther.mJustifyContent ||
mJustifyItems != aOther.mJustifyItems) {
mJustifyItems != aOther.mJustifyItems ||
mJustifySelf != aOther.mJustifySelf) {
NS_UpdateHint(hint, nsChangeHint_NeedReflow);
}
@ -1672,6 +1675,43 @@ nsStylePosition::WidthCoordDependsOnContainer(const nsStyleCoord &aCoord)
aCoord.GetIntValue() == NS_STYLE_WIDTH_AVAILABLE));
}
static nsStyleContext*
GetAlignmentContainer(nsStyleContext* aParent,
const nsStylePosition** aPosition,
const nsStyleDisplay** aDisplay)
{
while (aParent &&
aParent->StyleDisplay()->mDisplay == NS_STYLE_DISPLAY_CONTENTS) {
aParent = aParent->GetParent();
}
if (aParent) {
*aPosition = aParent->StylePosition();
*aDisplay = aParent->StyleDisplay();
}
return aParent;
}
uint8_t
nsStylePosition::MapLeftRightToStart(uint8_t aAlign, LogicalAxis aAxis,
const nsStyleDisplay* aDisplay) const
{
auto val = aAlign & ~NS_STYLE_ALIGN_FLAG_BITS;
if (val == NS_STYLE_ALIGN_LEFT || val == NS_STYLE_ALIGN_RIGHT) {
switch (aDisplay->mDisplay) {
case NS_STYLE_DISPLAY_FLEX:
case NS_STYLE_DISPLAY_INLINE_FLEX:
// XXX TODO
// NOTE: make sure to strip off 'legacy' bit when mapping to 'start'
break;
default:
if (aAxis == eLogicalAxisBlock) {
return NS_STYLE_ALIGN_START | (aAlign & NS_STYLE_ALIGN_FLAG_BITS);
}
}
}
return aAlign;
}
uint8_t
nsStylePosition::ComputedJustifyItems(const nsStyleDisplay* aDisplay,
nsStyleContext* aParent) const
@ -1691,6 +1731,30 @@ nsStylePosition::ComputedJustifyItems(const nsStyleDisplay* aDisplay,
: NS_STYLE_JUSTIFY_START;
}
uint8_t
nsStylePosition::ComputedJustifySelf(const nsStyleDisplay* aDisplay,
nsStyleContext* aParent) const
{
const nsStylePosition* containerPos = this;
const nsStyleDisplay* containerDisp = aDisplay;
GetAlignmentContainer(aParent, &containerPos, &containerDisp);
if (mJustifySelf != NS_STYLE_JUSTIFY_AUTO) {
return containerPos->MapLeftRightToStart(mJustifySelf, eLogicalAxisInline,
containerDisp);
}
if (MOZ_UNLIKELY(aDisplay->IsAbsolutelyPositionedStyle())) {
return NS_STYLE_JUSTIFY_AUTO;
}
if (MOZ_LIKELY(aParent)) {
auto inheritedJustifyItems = aParent->StylePosition()->
ComputedJustifyItems(aParent->StyleDisplay(), aParent->GetParent());
inheritedJustifyItems &= ~NS_STYLE_JUSTIFY_LEGACY;
return containerPos->MapLeftRightToStart(inheritedJustifyItems,
eLogicalAxisInline, containerDisp);
}
return NS_STYLE_JUSTIFY_START;
}
// --------------------
// nsStyleTable
//

View File

@ -1403,6 +1403,13 @@ struct nsStylePosition {
uint8_t ComputedJustifyItems(const nsStyleDisplay* aDisplay,
nsStyleContext* aParent) const;
/**
* Return the computed value for 'justify-self' given our 'display' value in
* aDisplay and the parent StyleContext aParent (or null for the root).
*/
uint8_t ComputedJustifySelf(const nsStyleDisplay* aDisplay,
nsStyleContext* aParent) const;
Position mObjectPosition; // [reset]
nsStyleSides mOffset; // [reset] coord, percent, calc, auto
nsStyleCoord mWidth; // [reset] coord, percent, enum, calc, auto
@ -1423,7 +1430,12 @@ struct nsStylePosition {
uint8_t mAlignSelf; // [reset] see nsStyleConsts.h
private:
friend class nsRuleNode;
// Helper for the ComputedAlign/Justify* methods.
uint8_t MapLeftRightToStart(uint8_t aAlign, mozilla::LogicalAxis aAxis,
const nsStyleDisplay* aDisplay) const;
uint8_t mJustifyItems; // [reset] see nsStyleConsts.h
uint8_t mJustifySelf; // [reset] see nsStyleConsts.h
public:
uint8_t mFlexDirection; // [reset] see nsStyleConsts.h
uint8_t mFlexWrap; // [reset] see nsStyleConsts.h

View File

@ -4086,6 +4086,18 @@ var gCSSProperties = {
"safe left legacy", "legacy left legacy", "baseline true",
"safe true", "safe left true", "safe stretch" ]
},
"justify-self": {
domProp: "justifySelf",
inherited: false,
type: CSS_TYPE_LONGHAND,
initial_values: [ "auto", "start" ],
other_values: [ "end", "flex-start", "flex-end", "self-start",
"self-end", "center", "left", "right", "baseline",
"last-baseline", "stretch", "left true", "true right",
"safe right", "center safe" ],
invalid_values: [ "space-between", "abc", "30px", "none",
"legacy left", "right legacy" ]
},
"flex": {
domProp: "flex",
inherited: false,