Bug 1176782 part 5 - [css-align] Implement additional syntax and values for the 'align-self' property in the style system. r=cam

This commit is contained in:
Mats Palmgren 2015-11-03 15:18:06 +01:00
parent 343fce8c76
commit ab2709bc55
10 changed files with 80 additions and 99 deletions

View File

@ -1565,8 +1565,8 @@ FlexItem::FlexItem(nsHTMLReflowState& aFlexItemReflowState,
mIsStretched(false),
mIsStrut(false),
// mNeedsMinSizeAutoResolution is initialized in CheckForMinSizeAuto()
mWM(aFlexItemReflowState.GetWritingMode()),
mAlignSelf(aFlexItemReflowState.mStylePosition->mAlignSelf)
mWM(aFlexItemReflowState.GetWritingMode())
// mAlignSelf, see below
{
MOZ_ASSERT(mFrame, "expecting a non-null child frame");
MOZ_ASSERT(mFrame->GetType() != nsGkAtoms::placeholderFrame,
@ -1574,6 +1574,15 @@ FlexItem::FlexItem(nsHTMLReflowState& aFlexItemReflowState,
MOZ_ASSERT(!(mFrame->GetStateBits() & NS_FRAME_OUT_OF_FLOW),
"out-of-flow frames should not be treated as flex items");
mAlignSelf = aFlexItemReflowState.mStylePosition->ComputedAlignSelf(
aFlexItemReflowState.mStyleDisplay,
mFrame->StyleContext()->GetParent());
if (MOZ_UNLIKELY(mAlignSelf == NS_STYLE_ALIGN_AUTO)) {
// Happens in rare edge cases when 'position' was ignored by the frame
// constructor (and the style system computed 'auto' based on 'position').
mAlignSelf = NS_STYLE_ALIGN_STRETCH;
}
SetFlexBaseSizeAndMainSize(aFlexBaseSize);
CheckForMinSizeAuto(aFlexItemReflowState, aAxisTracker);
@ -1592,13 +1601,6 @@ FlexItem::FlexItem(nsHTMLReflowState& aFlexItemReflowState,
}
#endif // DEBUG
// Resolve "align-self: auto" to parent's "align-items" value.
if (mAlignSelf == NS_STYLE_ALIGN_SELF_AUTO) {
auto parent = mFrame->StyleContext()->GetParent();
mAlignSelf =
parent->StylePosition()->ComputedAlignItems(parent->StyleDisplay());
}
// If the flex item's inline axis is the same as the cross axis, then
// 'align-self:baseline' is identical to 'flex-start'. If that's the case, we
// just directly convert our align-self value here, so that we don't have to

View File

@ -10634,6 +10634,8 @@ CSSParserImpl::ParsePropertyByFunction(nsCSSProperty aPropID)
return ParseRect(eCSSProperty_image_region);
case eCSSProperty_align_items:
return ParseAlignItemsSelfJustifySelf(aPropID);
case eCSSProperty_align_self:
return ParseAlignItemsSelfJustifySelf(aPropID);
case eCSSProperty_justify_content:
return ParseAlignJustifyContent(aPropID);
case eCSSProperty_justify_items:

View File

@ -1606,12 +1606,12 @@ CSS_PROP_POSITION(
align-self,
align_self,
AlignSelf,
CSS_PROPERTY_PARSE_VALUE,
CSS_PROPERTY_PARSE_FUNCTION,
"",
VARIANT_HK,
kAlignSelfKTable,
offsetof(nsStylePosition, mAlignSelf),
eStyleAnimType_EnumU8)
0,
nullptr,
CSS_PROP_NO_OFFSET,
eStyleAnimType_None)
CSS_PROP_SHORTHAND(
flex,
flex,

View File

@ -1340,17 +1340,6 @@ const KTableValue nsCSSProps::kAlignContentKTable[] = {
eCSSKeyword_UNKNOWN,-1
};
// Note: 'align-self' takes the same keywords as 'align-items', plus 'auto'.
const KTableValue nsCSSProps::kAlignSelfKTable[] = {
eCSSKeyword_flex_start, NS_STYLE_ALIGN_FLEX_START,
eCSSKeyword_flex_end, NS_STYLE_ALIGN_FLEX_END,
eCSSKeyword_center, NS_STYLE_ALIGN_CENTER,
eCSSKeyword_baseline, NS_STYLE_ALIGN_BASELINE,
eCSSKeyword_stretch, NS_STYLE_ALIGN_STRETCH,
eCSSKeyword_auto, NS_STYLE_ALIGN_SELF_AUTO,
eCSSKeyword_UNKNOWN,-1
};
const KTableValue nsCSSProps::kFlexDirectionKTable[] = {
eCSSKeyword_row, NS_STYLE_FLEX_DIRECTION_ROW,
eCSSKeyword_row_reverse, NS_STYLE_FLEX_DIRECTION_ROW_REVERSE,

View File

@ -1336,6 +1336,7 @@ nsCSSValue::AppendToString(nsCSSProperty aProperty, nsAString& aResult,
}
case eCSSProperty_align_items:
case eCSSProperty_align_self:
case eCSSProperty_justify_items:
case eCSSProperty_justify_self:
AppendAlignJustifyValueToString(intValue, aResult);

View File

@ -3870,32 +3870,6 @@ nsComputedDOMStyle::DoGetAlignContent()
return val;
}
CSSValue*
nsComputedDOMStyle::DoGetAlignSelf()
{
nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue;
uint8_t computedAlignSelf = StylePosition()->mAlignSelf;
if (computedAlignSelf == NS_STYLE_ALIGN_SELF_AUTO) {
// "align-self: auto" needs to compute to parent's align-items value.
nsStyleContext* parentStyleContext = mStyleContext->GetParent();
if (parentStyleContext) {
computedAlignSelf = parentStyleContext->StylePosition()->
ComputedAlignItems(parentStyleContext->StyleDisplay());
} else {
// No parent --> use default.
computedAlignSelf = NS_STYLE_ALIGN_STRETCH; // XXX temporary, will be removed in later patch
}
}
MOZ_ASSERT(computedAlignSelf != NS_STYLE_ALIGN_SELF_AUTO,
"Should have swapped out 'auto' for something non-auto");
val->SetIdent(
nsCSSProps::ValueToKeywordEnum(computedAlignSelf,
nsCSSProps::kAlignSelfKTable));
return val;
}
CSSValue*
nsComputedDOMStyle::DoGetFlexBasis()
{
@ -3972,6 +3946,18 @@ nsComputedDOMStyle::DoGetAlignItems()
return val;
}
CSSValue*
nsComputedDOMStyle::DoGetAlignSelf()
{
nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue;
auto align = StylePosition()->
ComputedAlignSelf(StyleDisplay(), mStyleContext->GetParent());
nsAutoString str;
nsCSSValue::AppendAlignJustifyValueToString(align, str);
val->SetString(str);
return val;
}
CSSValue*
nsComputedDOMStyle::DoGetJustifyContent()
{

View File

@ -7820,54 +7820,26 @@ nsRuleNode::ComputePositionData(void* aStartStruct,
}
// align-self: enum, inherit, initial
// NOTE: align-self's initial value is the special keyword "auto", which is
// supposed to compute to our parent's computed value of "align-items". So
// technically, "auto" itself is never a valid computed value for align-self,
// since it always computes to something else. Despite that, we do actually
// store "auto" in nsStylePosition::mAlignSelf, as NS_STYLE_ALIGN_SELF_AUTO
// (and then resolve it as-necessary). We do this because "auto" is the
// initial value for this property, so if we were to actually resolve it in
// nsStylePosition, we'd never be able to share any nsStylePosition structs
// in the rule tree, since their mAlignSelf values would depend on the parent
// style, by default.
if (aRuleData->ValueForAlignSelf()->GetUnit() == eCSSUnit_Inherit) {
// Special handling for "align-self: inherit", in case we're inheriting
// "align-self: auto", in which case we need to resolve the parent's "auto"
// and inherit that resolved value.
uint8_t inheritedAlignSelf = parentPos->mAlignSelf;
if (inheritedAlignSelf == NS_STYLE_ALIGN_SELF_AUTO) {
if (!parentContext) {
// We're the root node. Nothing to inherit from --> just use default
// value.
inheritedAlignSelf = NS_STYLE_ALIGN_AUTO; // XXX will be removed in next patch
} else {
// Our parent's "auto" value should resolve to our grandparent's value
// for "align-items". So, that's what we're supposed to inherit.
nsStyleContext* grandparentContext = parentContext->GetParent();
if (!grandparentContext) {
// No grandparent --> our parent is the root node, so its
// "align-self: auto" computes to the default "align-items" value:
inheritedAlignSelf = NS_STYLE_ALIGN_AUTO; // XXX will be removed in next patch
} else {
// Normal case -- we have a grandparent.
// Its "align-items" value is what we should end up inheriting.
const nsStylePosition* grandparentPos =
grandparentContext->StylePosition();
inheritedAlignSelf = grandparentPos->ComputedAlignItems(grandparentContext->StyleDisplay());
aContext->AddStyleBit(NS_STYLE_USES_GRANDANCESTOR_STYLE);
}
const auto& alignSelfValue = *aRuleData->ValueForAlignSelf();
if (MOZ_UNLIKELY(alignSelfValue.GetUnit() == eCSSUnit_Inherit)) {
if (MOZ_LIKELY(parentContext)) {
nsStyleContext* grandparentContext = parentContext->GetParent();
if (MOZ_LIKELY(grandparentContext)) {
aContext->AddStyleBit(NS_STYLE_USES_GRANDANCESTOR_STYLE);
}
pos->mAlignSelf =
parentPos->ComputedAlignSelf(parentContext->StyleDisplay(),
grandparentContext);
} else {
pos->mAlignSelf = NS_STYLE_ALIGN_START;
}
pos->mAlignSelf = inheritedAlignSelf;
conditions.SetUncacheable();
} else {
SetDiscrete(*aRuleData->ValueForAlignSelf(),
SetDiscrete(alignSelfValue,
pos->mAlignSelf, conditions,
SETDSC_ENUMERATED | SETDSC_UNSET_INITIAL,
parentPos->mAlignSelf, // (unused -- we handled inherit above)
NS_STYLE_ALIGN_SELF_AUTO, // initial == auto
0, 0, 0, 0);
parentPos->mAlignSelf, // unused, we handle 'inherit' above
NS_STYLE_ALIGN_AUTO, 0, 0, 0, 0);
}
// justify-content: enum, inherit, initial

View File

@ -1433,7 +1433,7 @@ nsStylePosition::nsStylePosition(void)
mBoxSizing = NS_STYLE_BOX_SIZING_CONTENT;
mAlignContent = NS_STYLE_ALIGN_CONTENT_STRETCH;
mAlignItems = NS_STYLE_ALIGN_AUTO;
mAlignSelf = NS_STYLE_ALIGN_SELF_AUTO;
mAlignSelf = NS_STYLE_ALIGN_AUTO;
mJustifyContent = NS_STYLE_JUSTIFY_AUTO;
mJustifyItems = NS_STYLE_JUSTIFY_AUTO;
mJustifySelf = NS_STYLE_JUSTIFY_AUTO;
@ -1706,6 +1706,26 @@ nsStylePosition::ComputedAlignItems(const nsStyleDisplay* aDisplay) const
: NS_STYLE_ALIGN_START;
}
uint8_t
nsStylePosition::ComputedAlignSelf(const nsStyleDisplay* aDisplay,
nsStyleContext* aParent) const
{
if (mAlignSelf != NS_STYLE_ALIGN_AUTO) {
return MapLeftRightToStart(mAlignSelf, eLogicalAxisBlock, aDisplay);
}
if (MOZ_UNLIKELY(aDisplay->IsAbsolutelyPositionedStyle())) {
return NS_STYLE_ALIGN_AUTO;
}
if (MOZ_LIKELY(aParent)) {
auto parentAlignItems = aParent->StylePosition()->
ComputedAlignItems(aParent->StyleDisplay());
MOZ_ASSERT(!(parentAlignItems & NS_STYLE_ALIGN_LEGACY),
"align-items can't have 'legacy'");
return MapLeftRightToStart(parentAlignItems, eLogicalAxisBlock, aDisplay);
}
return NS_STYLE_ALIGN_START;
}
uint16_t
nsStylePosition::ComputedJustifyContent(const nsStyleDisplay* aDisplay) const
{

View File

@ -1402,6 +1402,13 @@ struct nsStylePosition {
*/
uint8_t ComputedAlignItems(const nsStyleDisplay* aDisplay) const;
/**
* Return the computed value for 'align-self' given our 'display' value in
* aDisplay and the parent StyleContext aParent (or null for the root).
*/
uint8_t ComputedAlignSelf(const nsStyleDisplay* aDisplay,
nsStyleContext* aParent) const;
/**
* Return the computed value for 'justify-content' given our 'display' value
* in aDisplay.
@ -1438,7 +1445,6 @@ struct nsStylePosition {
uint8_t mGridAutoFlow; // [reset] enumerated. See nsStyleConsts.h
uint8_t mBoxSizing; // [reset] see nsStyleConsts.h
uint8_t mAlignContent; // [reset] see nsStyleConsts.h
uint8_t mAlignSelf; // [reset] see nsStyleConsts.h
private:
friend class nsRuleNode;
// Helper for the ComputedAlign/Justify* methods.
@ -1446,6 +1452,7 @@ private:
const nsStyleDisplay* aDisplay) const;
uint8_t mAlignItems; // [reset] see nsStyleConsts.h
uint8_t mAlignSelf; // [reset] see nsStyleConsts.h
uint16_t mJustifyContent; // [reset] fallback value in the high byte
uint8_t mJustifyItems; // [reset] see nsStyleConsts.h
uint8_t mJustifySelf; // [reset] see nsStyleConsts.h

View File

@ -4071,10 +4071,12 @@ var gCSSProperties = {
domProp: "alignSelf",
inherited: false,
type: CSS_TYPE_LONGHAND,
// (Assuming defaults on the parent, 'auto' will compute to 'stretch'.)
initial_values: [ "auto", "stretch" ],
other_values: [ "flex-start", "flex-end", "center", "baseline" ],
invalid_values: [ "space-between", "abc", "30px" ]
// (Assuming defaults on the parent, 'auto' will compute to 'start'.)
initial_values: [ "auto", "start" ],
other_values: [ "flex-start", "flex-end", "center", "stretch",
"baseline", "last-baseline", "right safe", "true center",
"self-start", "self-end safe" ],
invalid_values: [ "space-between", "abc", "30px", "stretch safe", "safe" ]
},
"justify-content": {
domProp: "justifyContent",