summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFranklinDM <mrmineshafter17@gmail.com>2022-04-06 23:59:01 +0800
committerFranklinDM <mrmineshafter17@gmail.com>2022-04-07 18:35:49 +0800
commit79b640795aacac89e67043a22cb3ceb622bd0864 (patch)
tree21a5ef80ff911eb79f4fd7787f40f59609a13001
parent0b75a2a787eeec1c87f7d6f3fa0d114c00f950f8 (diff)
downloaduxp-79b640795aacac89e67043a22cb3ceb622bd0864.tar.gz
Issue #1370 - Part 3: Implement `content` keyword for `flex-basis` property
Partially based on https://bugzilla.mozilla.org/show_bug.cgi?id=1105111
-rw-r--r--layout/generic/nsContainerFrame.cpp25
-rw-r--r--layout/generic/nsFrame.cpp16
-rw-r--r--layout/style/nsCSSKeywordList.h1
-rw-r--r--layout/style/nsCSSParser.cpp4
-rw-r--r--layout/style/nsCSSPropList.h2
-rw-r--r--layout/style/nsCSSProps.cpp14
-rw-r--r--layout/style/nsCSSProps.h1
-rw-r--r--layout/style/nsComputedDOMStyle.cpp2
-rw-r--r--layout/style/nsStyleConsts.h6
9 files changed, 63 insertions, 8 deletions
diff --git a/layout/generic/nsContainerFrame.cpp b/layout/generic/nsContainerFrame.cpp
index 125d602635..dd20ccffee 100644
--- a/layout/generic/nsContainerFrame.cpp
+++ b/layout/generic/nsContainerFrame.cpp
@@ -944,8 +944,29 @@ nsContainerFrame::ComputeAutoSize(nsRenderingContext* aRenderingContext,
aBorder.ISize(aWM) - aPadding.ISize(aWM);
// replaced elements always shrink-wrap
if ((aFlags & ComputeSizeFlags::eShrinkWrap) || IsFrameOfType(eReplaced)) {
- // don't bother setting it if the result won't be used
- if (StylePosition()->ISize(aWM).GetUnit() == eStyleUnit_Auto) {
+ const nsStylePosition* position = StylePosition();
+
+ bool isFlexBasisContent = false;
+ if (IsFlexItem()) {
+ uint32_t flexDirection =
+ GetParent()->StylePosition()->mFlexDirection;
+ bool isInlineFlexItem =
+ flexDirection == NS_STYLE_FLEX_DIRECTION_ROW ||
+ flexDirection == NS_STYLE_FLEX_DIRECTION_ROW_REVERSE;
+ isFlexBasisContent =
+ position->mFlexBasis.GetUnit() == eStyleUnit_Enumerated &&
+ position->mFlexBasis.GetIntValue() == NS_STYLE_FLEX_BASIS_CONTENT &&
+ isInlineFlexItem;
+ }
+
+ // Only bother computing our 'auto' ISize if the result will be used.
+ // It'll be used under two scenarios:
+ // - If our ISize property is itself 'auto'.
+ // - If we're using flex-basis in place of our ISize property (i.e. we're a
+ // flex item with our inline axis being the main axis), AND we have
+ // flex-basis:content.
+ bool isAuto = position->ISize(aWM).GetUnit() == eStyleUnit_Auto;
+ if (isAuto || isFlexBasisContent) {
result.ISize(aWM) = ShrinkWidthToFit(aRenderingContext, availBased, aFlags);
}
} else {
diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp
index 99442e681f..141c148673 100644
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -4647,11 +4647,23 @@ nsFrame::SetCoordToFlexBasis(bool aIsInlineFlexItem,
return;
}
+ const nsStyleCoord* newCoord = aFlexBasis;
+
+ // Having 'content' as the value of the 'flex-basis' property is
+ // equivalent to setting both 'flex-basis' and the main size
+ // properties to 'auto', which is why a dummy 'auto' value will
+ // be used here for the main size property.
+ if (aFlexBasis->GetUnit() == eStyleUnit_Enumerated &&
+ aFlexBasis->GetIntValue() == NS_STYLE_FLEX_BASIS_CONTENT) {
+ static const nsStyleCoord autoStyleCoord(eStyleUnit_Auto);
+ newCoord = &autoStyleCoord;
+ }
+
// Override whichever styleCoord is in the flex container's main axis
if (aIsInlineFlexItem) {
- *aInlineStyle = aFlexBasis;
+ *aInlineStyle = newCoord;
} else {
- *aBlockStyle = aFlexBasis;
+ *aBlockStyle = newCoord;
}
}
diff --git a/layout/style/nsCSSKeywordList.h b/layout/style/nsCSSKeywordList.h
index 2629127fae..7e661bc483 100644
--- a/layout/style/nsCSSKeywordList.h
+++ b/layout/style/nsCSSKeywordList.h
@@ -205,6 +205,7 @@ CSS_KEY(column, column)
CSS_KEY(column-reverse, column_reverse)
CSS_KEY(condensed, condensed)
CSS_KEY(contain, contain)
+CSS_KEY(content, content)
CSS_KEY(content-box, content_box)
CSS_KEY(contents, contents)
CSS_KEY(context-fill, context_fill)
diff --git a/layout/style/nsCSSParser.cpp b/layout/style/nsCSSParser.cpp
index 0899e4e4ee..b409bfed7e 100644
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -8574,7 +8574,7 @@ CSSParserImpl::ParseFlex()
// "a unitless zero that is not already preceded by two flex factors must be
// interpreted as a flex factor.
if (ParseNonNegativeVariant(tmpVal, flexBasisVariantMask | VARIANT_NUMBER,
- nsCSSProps::kWidthKTable) != CSSParseResult::Ok) {
+ nsCSSProps::kFlexBasisKTable) != CSSParseResult::Ok) {
// First component was not a valid flex-basis or flex-grow value. Fail.
return false;
}
@@ -8623,7 +8623,7 @@ CSSParserImpl::ParseFlex()
if (!wasFirstComponentFlexBasis) {
CSSParseResult result =
ParseNonNegativeVariant(tmpVal, flexBasisVariantMask,
- nsCSSProps::kWidthKTable);
+ nsCSSProps::kFlexBasisKTable);
if (result == CSSParseResult::Error) {
return false;
} else if (result == CSSParseResult::Ok) {
diff --git a/layout/style/nsCSSPropList.h b/layout/style/nsCSSPropList.h
index b51867f3ce..ae5de51e5a 100644
--- a/layout/style/nsCSSPropList.h
+++ b/layout/style/nsCSSPropList.h
@@ -1758,7 +1758,7 @@ CSS_PROP_POSITION(
// its own code to parse each subproperty. It does not depend on the
// longhand parsing defined here.
VARIANT_AHKLP | VARIANT_CALC,
- kWidthKTable,
+ kFlexBasisKTable,
offsetof(nsStylePosition, mFlexBasis),
eStyleAnimType_Coord)
CSS_PROP_POSITION(
diff --git a/layout/style/nsCSSProps.cpp b/layout/style/nsCSSProps.cpp
index 7d4e008b45..e3cd802417 100644
--- a/layout/style/nsCSSProps.cpp
+++ b/layout/style/nsCSSProps.cpp
@@ -2261,6 +2261,20 @@ const KTableEntry nsCSSProps::kWidthKTable[] = {
{ eCSSKeyword_UNKNOWN, -1 }
};
+// This must be the same as kWidthKTable, but just with 'content' added:
+const KTableEntry nsCSSProps::kFlexBasisKTable[] = {
+ { eCSSKeyword__moz_max_content, NS_STYLE_WIDTH_MAX_CONTENT },
+ { eCSSKeyword__moz_min_content, NS_STYLE_WIDTH_MIN_CONTENT },
+ { eCSSKeyword__moz_fit_content, NS_STYLE_WIDTH_FIT_CONTENT },
+ { eCSSKeyword__moz_available, NS_STYLE_WIDTH_AVAILABLE },
+ { eCSSKeyword_content, NS_STYLE_FLEX_BASIS_CONTENT },
+ { eCSSKeyword_UNKNOWN, -1 }
+};
+static_assert(ArrayLength(nsCSSProps::kFlexBasisKTable) ==
+ ArrayLength(nsCSSProps::kWidthKTable) + 1,
+ "kFlexBasisKTable should have the same entries as "
+ "kWidthKTable, plus one more for 'content'");
+
const KTableEntry nsCSSProps::kWindowDraggingKTable[] = {
{ eCSSKeyword_default, StyleWindowDragging::Default },
{ eCSSKeyword_drag, StyleWindowDragging::Drag },
diff --git a/layout/style/nsCSSProps.h b/layout/style/nsCSSProps.h
index 7b8c56860c..cf7ffda78f 100644
--- a/layout/style/nsCSSProps.h
+++ b/layout/style/nsCSSProps.h
@@ -892,6 +892,7 @@ public:
static const KTableEntry kVolumeKTable[];
static const KTableEntry kWhitespaceKTable[];
static const KTableEntry kWidthKTable[]; // also min-width, max-width
+ static const KTableEntry kFlexBasisKTable[];
static const KTableEntry kWindowDraggingKTable[];
static const KTableEntry kWindowShadowKTable[];
static const KTableEntry kWordBreakKTable[];
diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp
index eb56559d93..b3c4ccc148 100644
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -4424,7 +4424,7 @@ nsComputedDOMStyle::DoGetFlexBasis()
// }
SetValueToCoord(val, StylePosition()->mFlexBasis, true,
- nullptr, nsCSSProps::kWidthKTable);
+ nullptr, nsCSSProps::kFlexBasisKTable);
return val.forget();
}
diff --git a/layout/style/nsStyleConsts.h b/layout/style/nsStyleConsts.h
index 8966932626..4d2043cc47 100644
--- a/layout/style/nsStyleConsts.h
+++ b/layout/style/nsStyleConsts.h
@@ -776,6 +776,12 @@ enum class StyleDisplay : uint8_t {
#define NS_STYLE_WIDTH_MIN_CONTENT 1
#define NS_STYLE_WIDTH_FIT_CONTENT 2
#define NS_STYLE_WIDTH_AVAILABLE 3
+// The 'content' keyword is only valid for 'flex-basis' (not for 'width').
+// Since the 'flex-basis' property accepts exactly the same values as 'width',
+// this 'flex-basis'-specific enumerated value is listed alongside the
+// 'width' ones, to be sure we don't accidentally overload this numeric
+// value with two different meanings if new 'width' keywords are added.
+#define NS_STYLE_FLEX_BASIS_CONTENT 4
// See nsStyleDisplay.mPosition
#define NS_STYLE_POSITION_STATIC 0