diff options
author | Moonchild <moonchild@palemoon.org> | 2022-04-08 16:08:33 +0000 |
---|---|---|
committer | Moonchild <moonchild@palemoon.org> | 2022-04-08 16:08:33 +0000 |
commit | d5ae68701b8367841e8e1c994d68e324164ca0ce (patch) | |
tree | 3b4f37ea27b31296277ef1ae5a6b1e2edfe5b62b /layout | |
parent | 330b866f465f58e1fed01e819eef7043d6c9f628 (diff) | |
parent | acf30bc5f4cd2dd1c3e01a38b1a766375d97fa01 (diff) | |
download | uxp-d5ae68701b8367841e8e1c994d68e324164ca0ce.tar.gz |
Merge pull request 'Implement 'content' keyword for 'flex-basis' property and address spec changes' (#1854) from FranklinDM/UXP-contrib:work_css-flex-basis-content into master
Reviewed-on: https://repo.palemoon.org/MoonchildProductions/UXP/pulls/1854
Diffstat (limited to 'layout')
24 files changed, 1340 insertions, 59 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 14d411e6ab..458b18abd9 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -4635,6 +4635,54 @@ nsFrame::GetIntrinsicRatio() return AspectRatio(); } +void +nsFrame::SetCoordToFlexBasis(bool aIsInlineFlexItem, + bool aIntrinsic, + const nsStyleCoord* aFlexBasis, + const nsStyleCoord** aInlineStyle, + const nsStyleCoord** aBlockStyle) +{ + auto mainAxisCoord = aIsInlineFlexItem ? + aInlineStyle : + aBlockStyle; + // We have a used flex-basis of 'content' if flex-basis explicitly has that + // value, OR if flex-basis is 'auto' (deferring to the main-size property) + // and the main-size property is also 'auto'. + // See https://drafts.csswg.org/css-flexbox-1/#valdef-flex-basis-auto + if ((aFlexBasis->GetUnit() == eStyleUnit_Enumerated && + aFlexBasis->GetIntValue() == NS_STYLE_FLEX_BASIS_CONTENT) || + (aFlexBasis->GetUnit() == eStyleUnit_Auto && + (*mainAxisCoord)->GetUnit() == eStyleUnit_Auto)) { + // If we get here, we're resolving the flex base size for a flex item, + // and we fall into the flexbox spec section 9.2 step 3, substep C (if + // we have a definite cross size) or E (if not). And specifically: + // + // * If we have a definite cross size, we're supposed to resolve our + // main-size based on that and our intrinsic ratio. + // * Otherwise, we're supposed to produce our max-content size. + // + // Conveniently, we can handle both of those scenarios (regardless of + // which substep we fall into) by using the 'auto' keyword for our + // main-axis coordinate here. (This makes sense, because the spec is + // effectively trying to produce the 'auto' sizing behavior). + if (aIntrinsic) { + static const nsStyleCoord autoStyleCoord(eStyleUnit_Auto); + *mainAxisCoord = &autoStyleCoord; + } else { + // (Note: if our main axis is the block axis, then this 'max-content' + // value will be treated like 'auto', via the IsAutoBSize() call below.) + static const nsStyleCoord maxContStyleCoord(NS_STYLE_WIDTH_MAX_CONTENT, + eStyleUnit_Enumerated); + *mainAxisCoord = &maxContStyleCoord; + } + } else if (aFlexBasis->GetUnit() != eStyleUnit_Auto) { + // For all other non-'auto' flex-basis values, we just swap in the + // flex-basis itself for the main-size property. + *mainAxisCoord = aFlexBasis; + } // else: flex-basis is 'auto', which is deferring to some explicit + // value in mainAxisCoord. So we proceed w/o touching mainAxisCoord. +} + /* virtual */ LogicalSize nsFrame::ComputeSize(nsRenderingContext* aRenderingContext, @@ -4689,35 +4737,14 @@ nsFrame::ComputeSize(nsRenderingContext* aRenderingContext, !(GetStateBits() & NS_FRAME_OUT_OF_FLOW)); bool isInlineFlexItem = false; if (isFlexItem) { - // Flex items use their "flex-basis" property in place of their main-size - // property (e.g. "width") for sizing purposes, *unless* they have - // "flex-basis:auto", in which case they use their main-size property after - // all. uint32_t flexDirection = GetParent()->StylePosition()->mFlexDirection; isInlineFlexItem = flexDirection == NS_STYLE_FLEX_DIRECTION_ROW || flexDirection == NS_STYLE_FLEX_DIRECTION_ROW_REVERSE; - // NOTE: The logic here should match the similar chunk for determining - // inlineStyleCoord and blockStyleCoord in - // nsFrame::ComputeSizeWithIntrinsicDimensions(). const nsStyleCoord* flexBasis = &(stylePos->mFlexBasis); - if (flexBasis->GetUnit() != eStyleUnit_Auto) { - if (isInlineFlexItem) { - inlineStyleCoord = flexBasis; - } else { - // One caveat for vertical flex items: We don't support enumerated - // values (e.g. "max-content") for height properties yet. So, if our - // computed flex-basis is an enumerated value, we'll just behave as if - // it were "auto", which means "use the main-size property after all" - // (which is "height", in this case). - // NOTE: Once we support intrinsic sizing keywords for "height", - // we should remove this check. - if (flexBasis->GetUnit() != eStyleUnit_Enumerated) { - blockStyleCoord = flexBasis; - } - } - } + SetCoordToFlexBasis(isInlineFlexItem, false, flexBasis, + &inlineStyleCoord, &blockStyleCoord); } // Compute inline-axis size @@ -4949,31 +4976,10 @@ nsFrame::ComputeSizeWithIntrinsicDimensions(nsRenderingContext* aRenderingConte } else { blockStyleCoord = imposedMainSizeStyleCoord.ptr(); } - } else { - // Flex items use their "flex-basis" property in place of their main-size - // property (e.g. "width") for sizing purposes, *unless* they have - // "flex-basis:auto", in which case they use their main-size property - // after all. - // NOTE: The logic here should match the similar chunk for determining - // inlineStyleCoord and blockStyleCoord in nsFrame::ComputeSize(). const nsStyleCoord* flexBasis = &(stylePos->mFlexBasis); - if (flexBasis->GetUnit() != eStyleUnit_Auto) { - if (isInlineFlexItem) { - inlineStyleCoord = flexBasis; - } else { - // One caveat for vertical flex items: We don't support enumerated - // values (e.g. "max-content") for height properties yet. So, if our - // computed flex-basis is an enumerated value, we'll just behave as if - // it were "auto", which means "use the main-size property after all" - // (which is "height", in this case). - // NOTE: Once we support intrinsic sizing keywords for "height", - // we should remove this check. - if (flexBasis->GetUnit() != eStyleUnit_Enumerated) { - blockStyleCoord = flexBasis; - } - } - } + SetCoordToFlexBasis(isInlineFlexItem, true, flexBasis, + &inlineStyleCoord, &blockStyleCoord); } } diff --git a/layout/generic/nsFrame.h b/layout/generic/nsFrame.h index d75555fec2..d703a62942 100644 --- a/layout/generic/nsFrame.h +++ b/layout/generic/nsFrame.h @@ -266,6 +266,17 @@ public: virtual mozilla::IntrinsicSize GetIntrinsicSize() override; virtual mozilla::AspectRatio GetIntrinsicRatio() override; + /** + * Helper function for determining if flex items should use their + * 'flex-basis' property instead of their main-size property, such + * as 'width', for sizing purposes. + */ + void SetCoordToFlexBasis(bool aIsInlineFlexItem, + bool aIntrinsic, + const nsStyleCoord* aFlexBasis, + const nsStyleCoord** aInlineStyle, + const nsStyleCoord** aBlockStyle); + virtual mozilla::LogicalSize ComputeSize(nsRenderingContext* aRenderingContext, mozilla::WritingMode aWM, @@ -295,7 +306,7 @@ public: // Compute tight bounds assuming this frame honours its border, background // and outline, its children's tight bounds, and nothing else. nsRect ComputeSimpleTightBounds(mozilla::gfx::DrawTarget* aDrawTarget) const; - + /** * A helper, used by |nsFrame::ComputeSize| (for frames that need to * override only this part of ComputeSize), that computes the size diff --git a/layout/reftests/w3c-css/submitted/flexbox/flexbox-flex-basis-content-001-ref.html b/layout/reftests/w3c-css/submitted/flexbox/flexbox-flex-basis-content-001-ref.html new file mode 100644 index 0000000000..b537711020 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-flex-basis-content-001-ref.html @@ -0,0 +1,77 @@ +<!DOCTYPE html> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<html> +<head> + <title>CSS Reftest Reference</title> + <meta charset="utf-8"> + <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com"> + <link rel="stylesheet" type="text/css" href="support/ahem.css"> + <style> + .container { + display: flex; + flex-direction: row; + justify-content: space-between; + border: 2px solid purple; + padding: 2px; + margin-bottom: 2em; + height: 50px; + width: 200px; + } + + .container > * { + flex-shrink: 0; + min-width: 0; + border: 2px solid teal; + } + + .smallText { font: 10px Ahem; } + .bigText { font: 20px Ahem; } + .spacerChild::before { + content: ''; + display: block; + background: brown; + height: 10px; + width: 10px; + } + .justPadding { + /* Empty div with 5px padding on each side */ + padding: 5px; + background: cyan; + } + canvas { background: fuchsia } + </style> +</head> +<body> +<!-- Flex items have unspecified size properties: --> +<div class="container"> + <div class="smallText">a b</div> + <div class="bigText">c</div> + <div class="spacerChild"></div> + <div class="justPadding"></div> + <canvas width="20"></canvas> +</div> + +<!-- Various specified main-size values, in testcase + (removed here in reference case, because they shouldn't affect sizing): --> +<div class="container"> + <div class="smallText">a b</div> + <div class="bigText">c</div> + <div class="spacerChild"></div> + <div class="justPadding"></div> + <canvas width="20"></canvas> +</div> + +<!-- Various specified cross-size values (should be honored): --> +<div class="container"> + <div class="smallText" style="height: 0px">a b</div> + <div class="bigText" style="height: 40px">c</div> + <div class="spacerChild" style="height: 20px"></div> + <div class="justPadding" style="height: 10px"></div> + <canvas width="20" style="height: 8px"></canvas> +</div> + +</body> +</html> diff --git a/layout/reftests/w3c-css/submitted/flexbox/flexbox-flex-basis-content-001a.html b/layout/reftests/w3c-css/submitted/flexbox/flexbox-flex-basis-content-001a.html new file mode 100644 index 0000000000..4227f68ff1 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-flex-basis-content-001a.html @@ -0,0 +1,83 @@ +<!DOCTYPE html> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<html> +<head> + <title> + CSS Test: Testing "flex-basis: content" in a row-oriented flex container + </title> + <meta charset="utf-8"> + <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com"> + <link rel="help" href="https://www.w3.org/TR/css-flexbox-1/#propdef-flex-basis"> + <link rel="match" href="flexbox-flex-basis-content-001-ref.html"> + <link rel="stylesheet" type="text/css" href="support/ahem.css"> + <style> + .container { + display: flex; + flex-direction: row; + justify-content: space-between; + border: 2px solid purple; + padding: 2px; + margin-bottom: 2em; + height: 50px; + width: 200px; + } + + .container > * { + /* All flex items have "flex-basis: content" (and zero flex-shrink and + min-main-size, to avoid any influence from those). */ + flex-basis: content; + flex-shrink: 0; + min-width: 0; + border: 2px solid teal; + } + + .smallText { font: 10px Ahem; } + .bigText { font: 20px Ahem; } + .spacerChild::before { + content: ''; + display: block; + background: brown; + height: 10px; + width: 10px; + } + .justPadding { + /* Empty div with 5px padding on each side */ + padding: 5px; + background: cyan; + } + canvas { background: fuchsia } + </style> +</head> +<body> +<!-- Flex items have unspecified size properties: --> +<div class="container"> + <div class="smallText">a b</div> + <div class="bigText">c</div> + <div class="spacerChild"></div> + <div class="justPadding"></div> + <canvas width="20"></canvas> +</div> + +<!-- Various specified main-size values (should be ignored): --> +<div class="container"> + <div class="smallText" style="width: 0px">a b</div> + <div class="bigText" style="width: 40px">c</div> + <div class="spacerChild" style="width: 20px"></div> + <div class="justPadding" style="width: 10px"></div> + <canvas width="20" style="width: 8px"></canvas> +</div> + +<!-- Various specified cross-size values (should be honored): --> +<div class="container"> + <div class="smallText" style="height: 0px">a b</div> + <div class="bigText" style="height: 40px">c</div> + <div class="spacerChild" style="height: 20px"></div> + <div class="justPadding" style="height: 10px"></div> + <canvas width="20" style="height: 8px"></canvas> +</div> + +</body> +</html> diff --git a/layout/reftests/w3c-css/submitted/flexbox/flexbox-flex-basis-content-001b.html b/layout/reftests/w3c-css/submitted/flexbox/flexbox-flex-basis-content-001b.html new file mode 100644 index 0000000000..489ce65d8f --- /dev/null +++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-flex-basis-content-001b.html @@ -0,0 +1,83 @@ +<!DOCTYPE html> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<html> +<head> + <title> + CSS Test: Testing "flex-basis: content" (set via the "flex" shorthand) + in a row-oriented flex container. + </title> + <meta charset="utf-8"> + <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com"> + <link rel="help" href="https://www.w3.org/TR/css-flexbox-1/#propdef-flex-basis"> + <link rel="match" href="flexbox-flex-basis-content-001-ref.html"> + <link rel="stylesheet" type="text/css" href="support/ahem.css"> + <style> + .container { + display: flex; + flex-direction: row; + justify-content: space-between; + border: 2px solid purple; + padding: 2px; + margin-bottom: 2em; + height: 50px; + width: 200px; + } + + .container > * { + /* All flex items have "flex-basis: content" (and zero flex-shrink and + min-main-size, to avoid any influence from those). */ + flex: 0 0 content; + min-width: 0; + border: 2px solid teal; + } + + .smallText { font: 10px Ahem; } + .bigText { font: 20px Ahem; } + .spacerChild::before { + content: ''; + display: block; + background: brown; + height: 10px; + width: 10px; + } + .justPadding { + /* Empty div with 5px padding on each side */ + padding: 5px; + background: cyan; + } + canvas { background: fuchsia } + </style> +</head> +<body> +<!-- Flex items have unspecified size properties: --> +<div class="container"> + <div class="smallText">a b</div> + <div class="bigText">c</div> + <div class="spacerChild"></div> + <div class="justPadding"></div> + <canvas width="20"></canvas> +</div> + +<!-- Various specified main-size values (should be ignored): --> +<div class="container"> + <div class="smallText" style="width: 0px">a b</div> + <div class="bigText" style="width: 40px">c</div> + <div class="spacerChild" style="width: 20px"></div> + <div class="justPadding" style="width: 10px"></div> + <canvas width="20" style="width: 8px"></canvas> +</div> + +<!-- Various specified cross-size values (should be honored): --> +<div class="container"> + <div class="smallText" style="height: 0px">a b</div> + <div class="bigText" style="height: 40px">c</div> + <div class="spacerChild" style="height: 20px"></div> + <div class="justPadding" style="height: 10px"></div> + <canvas width="20" style="height: 8px"></canvas> +</div> + +</body> +</html> diff --git a/layout/reftests/w3c-css/submitted/flexbox/flexbox-flex-basis-content-002-ref.html b/layout/reftests/w3c-css/submitted/flexbox/flexbox-flex-basis-content-002-ref.html new file mode 100644 index 0000000000..a7d1bcf77b --- /dev/null +++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-flex-basis-content-002-ref.html @@ -0,0 +1,78 @@ +<!DOCTYPE html> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<html> +<head> + <title>CSS Reftest Reference</title> + <meta charset="utf-8"> + <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com"> + <link rel="stylesheet" type="text/css" href="support/ahem.css"> + <style> + .container { + display: flex; + flex-direction: column; + justify-content: space-between; + border: 2px solid purple; + padding: 2px; + margin-right: 2em; + width: 50px; + height: 200px; + float: left; + } + + .container > * { + flex-shrink: 0; + min-height: 0; + border: 2px solid teal; + } + + .smallText { font: 10px Ahem; } + .bigText { font: 20px Ahem; } + .spacerChild::before { + content: ''; + display: block; + background: brown; + height: 10px; + width: 10px; + } + .justPadding { + /* Empty div with 5px padding on each side */ + padding: 5px; + background: cyan; + } + canvas { background: fuchsia } + </style> +</head> +<body> +<!-- Flex items have unspecified size properties: --> +<div class="container"> + <div class="smallText">a b</div> + <div class="bigText">c</div> + <div class="spacerChild"></div> + <div class="justPadding"></div> + <canvas height="20"></canvas> +</div> + +<!-- Various specified main-size values, in testcase + (removed here in reference case, because they shouldn't affect sizing): --> +<div class="container"> + <div class="smallText">a b</div> + <div class="bigText">c</div> + <div class="spacerChild"></div> + <div class="justPadding"></div> + <canvas height="20"></canvas> +</div> + +<!-- Various specified cross-size values (should be honored): --> +<div class="container"> + <div class="smallText" style="width: 0px">a b</div> + <div class="bigText" style="width: 40px">c</div> + <div class="spacerChild" style="width: 20px"></div> + <div class="justPadding" style="width: 10px"></div> + <canvas height="20" style="width: 8px"></canvas> +</div> + +</body> +</html> diff --git a/layout/reftests/w3c-css/submitted/flexbox/flexbox-flex-basis-content-002a.html b/layout/reftests/w3c-css/submitted/flexbox/flexbox-flex-basis-content-002a.html new file mode 100644 index 0000000000..481a3f2290 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-flex-basis-content-002a.html @@ -0,0 +1,84 @@ +<!DOCTYPE html> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<html> +<head> + <title> + CSS Test: Testing "flex-basis: content" in a column-oriented flex container + </title> + <meta charset="utf-8"> + <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com"> + <link rel="help" href="https://www.w3.org/TR/css-flexbox-1/#propdef-flex-basis"> + <link rel="match" href="flexbox-flex-basis-content-002-ref.html"> + <link rel="stylesheet" type="text/css" href="support/ahem.css"> + <style> + .container { + display: flex; + flex-direction: column; + justify-content: space-between; + border: 2px solid purple; + padding: 2px; + margin-right: 2em; + width: 50px; + height: 200px; + float: left; + } + + .container > * { + /* All flex items have "flex-basis: content" (and zero flex-shrink and + min-main-size, to avoid any influence from those). */ + flex-basis: content; + flex-shrink: 0; + min-height: 0; + border: 2px solid teal; + } + + .smallText { font: 10px Ahem; } + .bigText { font: 20px Ahem; } + .spacerChild::before { + content: ''; + display: block; + background: brown; + height: 10px; + width: 10px; + } + .justPadding { + /* Empty div with 5px padding on each side */ + padding: 5px; + background: cyan; + } + canvas { background: fuchsia } + </style> +</head> +<body> +<!-- Flex items have unspecified size properties: --> +<div class="container"> + <div class="smallText">a b</div> + <div class="bigText">c</div> + <div class="spacerChild"></div> + <div class="justPadding"></div> + <canvas height="20"></canvas> +</div> + +<!-- Various specified main-size values (should be ignored): --> +<div class="container"> + <div class="smallText" style="height: 0px">a b</div> + <div class="bigText" style="height: 40px">c</div> + <div class="spacerChild" style="height: 20px"></div> + <div class="justPadding" style="height: 10px"></div> + <canvas height="20" style="height: 8px"></canvas> +</div> + +<!-- Various specified cross-size values (should be honored): --> +<div class="container"> + <div class="smallText" style="width: 0px">a b</div> + <div class="bigText" style="width: 40px">c</div> + <div class="spacerChild" style="width: 20px"></div> + <div class="justPadding" style="width: 10px"></div> + <canvas height="20" style="width: 8px"></canvas> +</div> + +</body> +</html> diff --git a/layout/reftests/w3c-css/submitted/flexbox/flexbox-flex-basis-content-002b.html b/layout/reftests/w3c-css/submitted/flexbox/flexbox-flex-basis-content-002b.html new file mode 100644 index 0000000000..694e67242e --- /dev/null +++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-flex-basis-content-002b.html @@ -0,0 +1,84 @@ +<!DOCTYPE html> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<html> +<head> + <title> + CSS Test: Testing "flex-basis: content" (set via the "flex" shorthand) + in a column-oriented flex container. + </title> + <meta charset="utf-8"> + <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com"> + <link rel="help" href="https://www.w3.org/TR/css-flexbox-1/#propdef-flex-basis"> + <link rel="match" href="flexbox-flex-basis-content-002-ref.html"> + <link rel="stylesheet" type="text/css" href="support/ahem.css"> + <style> + .container { + display: flex; + flex-direction: column; + justify-content: space-between; + border: 2px solid purple; + padding: 2px; + margin-right: 2em; + width: 50px; + height: 200px; + float: left; + } + + .container > * { + /* All flex items have "flex-basis: content" (and zero flex-shrink and + min-main-size, to avoid any influence from those). */ + flex: 0 0 content; + min-height: 0; + border: 2px solid teal; + } + + .smallText { font: 10px Ahem; } + .bigText { font: 20px Ahem; } + .spacerChild::before { + content: ''; + display: block; + background: brown; + height: 10px; + width: 10px; + } + .justPadding { + /* Empty div with 5px padding on each side */ + padding: 5px; + background: cyan; + } + canvas { background: fuchsia } + </style> +</head> +<body> +<!-- Flex items have unspecified size properties: --> +<div class="container"> + <div class="smallText">a b</div> + <div class="bigText">c</div> + <div class="spacerChild"></div> + <div class="justPadding"></div> + <canvas height="20"></canvas> +</div> + +<!-- Various specified main-size values (should be ignored): --> +<div class="container"> + <div class="smallText" style="height: 0px">a b</div> + <div class="bigText" style="height: 40px">c</div> + <div class="spacerChild" style="height: 20px"></div> + <div class="justPadding" style="height: 10px"></div> + <canvas height="20" style="height: 8px"></canvas> +</div> + +<!-- Various specified cross-size values (should be honored): --> +<div class="container"> + <div class="smallText" style="width: 0px">a b</div> + <div class="bigText" style="width: 40px">c</div> + <div class="spacerChild" style="width: 20px"></div> + <div class="justPadding" style="width: 10px"></div> + <canvas height="20" style="width: 8px"></canvas> +</div> + +</body> +</html> diff --git a/layout/reftests/w3c-css/submitted/flexbox/flexbox-flex-basis-content-003-ref.html b/layout/reftests/w3c-css/submitted/flexbox/flexbox-flex-basis-content-003-ref.html new file mode 100644 index 0000000000..63ce9d7429 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-flex-basis-content-003-ref.html @@ -0,0 +1,103 @@ +<!DOCTYPE html> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<html> +<head> + <title>CSS Reftest Reference</title> + <meta charset="utf-8"> + <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com"> + <style> + .container { + clear: both; /* In this reference case, we use floats instead of + flex items (see below), so the container just + needs to reset the float state for each example. */ + } + + .item { + border: 2px solid teal; + float: left; /* Use floated elements as a reference for (hopefully) + max-content sized flex items in testcase. */ + } + ib { + display: inline-block; + background: blue; + border: 1px solid gray; + width: 15px; + height: 10px; + } + float { + float: left; + background: fuchsia; + border: 1px solid gray; + width: 15px; + height: 10px; + } + canvas { + background: brown; + border: 1px solid gray; + } + .innerFlex { + display: flex; + } + innerItem { + background: salmon; + border: 1px solid gray; + height: 10px; + width: 15px; + flex: none; + } + </style> +</head> +<body> +<!-- In testcase, flex item has several inline-blocks + (no spaces, to avoid any text-layout dependency): --> +<div class="container"> + <div class="item"><ib></ib><ib></ib><ib></ib></div> +</div> + +<!-- In testcase, flex item has several floats: --> +<div class="container"> + <div class="item"> + <float></float> + <float></float> + <float></float> + </div> +</div> + +<!-- In testcase, flex item has several inline replaced elements: + (no spaces, to avoid any text-layout dependency): --> +<div class="container"> + <div class="item"> + <canvas width="15" height="10"></canvas + ><canvas width="15" height="10"></canvas + ><canvas width="15" height="10"></canvas> + </div> +</div> + +<!-- In testcase, flex item *is* a replaced element: --> +<div class="container"> + <canvas class="item" width="25" height="10"></canvas> +</div> + +<!-- In testcase, flex item is itself a flex container: --> +<div class="container"> + <div class="item innerFlex"> + <innerItem></innerItem> + <innerItem></innerItem> + <innerItem></innerItem> + </div> +</div> + +<!-- In testcase, flex item is itself a multi-line flex container: --> +<div class="container"> + <div class="item innerFlex" style="flex-wrap: wrap"> + <innerItem></innerItem> + <innerItem></innerItem> + <innerItem></innerItem> + </div> +</div> + +</body> +</html> diff --git a/layout/reftests/w3c-css/submitted/flexbox/flexbox-flex-basis-content-003a.html b/layout/reftests/w3c-css/submitted/flexbox/flexbox-flex-basis-content-003a.html new file mode 100644 index 0000000000..83dbae0868 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-flex-basis-content-003a.html @@ -0,0 +1,123 @@ +<!DOCTYPE html> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<html> +<head> + <title> + CSS Test: Testing that explicit "flex-basis: content" is treated as + "max-content" when calculating flex base size + </title> + <meta charset="utf-8"> + <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com"> + <link rel="help" href="https://www.w3.org/TR/css-flexbox-1/#flex-base-size"> + <link rel="match" href="flexbox-flex-basis-content-003-ref.html"> + <style> + .container { + display: flex; + /* flex container has an extremely-constrained width (and items will + overflow horizontally). This is intentional, as part of stress-testing + item sizing. */ + width: 1px; + } + + .item { + /* We give all flex items "flex-basis: content". + We also give them zero flex-grow, flex-shrink, and min-main-size, so + that the flex base size entirely determines the flex item's size. */ + flex: 0 0 content; + min-width: 0; + border: 2px solid teal; + } + ib { + display: inline-block; + background: blue; + border: 1px solid gray; + width: 15px; + height: 10px; + } + float { + float: left; + background: fuchsia; + border: 1px solid gray; + width: 15px; + height: 10px; + } + canvas { + background: brown; + border: 1px solid gray; + } + .innerFlex { + display: flex; + } + innerItem { + background: salmon; + border: 1px solid gray; + height: 10px; + width: 15px; + flex: none; + } + </style> +</head> +<body> +<!-- The idea of this test is to be sure the UA is using the "max-content" size + (and not e.g. the "fit-content size") when resolving the flex base size + inside each flex container. To differentiate between max-content and + other intrinsic size possibilities (min-content/fit-content), we: + - use flex items with a large difference between its min-content size & + its max-content size (e.g. wrappable content). + - use a very small container (to compress the size, if the UA incorrectly + allows the size to be influenced by the container size). +--> + +<!-- Flex item has several inline-blocks + (no spaces, to avoid any text-layout dependency): --> +<div class="container"> + <div class="item"><ib></ib><ib></ib><ib></ib></div> +</div> + +<!-- Flex item has several floats: --> +<div class="container"> + <div class="item"> + <float></float> + <float></float> + <float></float> + </div> +</div> + +<!-- Flex item has several inline replaced elements: + (no spaces, to avoid any text-layout dependency): --> +<div class="container"> + <div class="item"> + <canvas width="15" height="10"></canvas + ><canvas width="15" height="10"></canvas + ><canvas width="15" height="10"></canvas> + </div> +</div> + +<!-- Flex item *is* a replaced element: --> +<div class="container"> + <canvas class="item" width="25" height="10"></canvas> +</div> + +<!-- Flex item is itself a flex container: --> +<div class="container"> + <div class="item innerFlex"> + <innerItem></innerItem> + <innerItem></innerItem> + <innerItem></innerItem> + </div> +</div> + +<!-- Flex item is itself a multi-line flex container: --> +<div class="container"> + <div class="item innerFlex" style="flex-wrap: wrap"> + <innerItem></innerItem> + <innerItem></innerItem> + <innerItem></innerItem> + </div> +</div> + +</body> +</html> diff --git a/layout/reftests/w3c-css/submitted/flexbox/flexbox-flex-basis-content-003b.html b/layout/reftests/w3c-css/submitted/flexbox/flexbox-flex-basis-content-003b.html new file mode 100644 index 0000000000..a81403c098 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-flex-basis-content-003b.html @@ -0,0 +1,124 @@ +<!DOCTYPE html> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<html> +<head> + <title> + CSS Test: Testing that used "flex-basis: content" is treated as + "max-content" when calculating flex base size + </title> + <meta charset="utf-8"> + <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com"> + <link rel="help" href="https://www.w3.org/TR/css-flexbox-1/#flex-base-size"> + <link rel="match" href="flexbox-flex-basis-content-003-ref.html"> + <style> + .container { + display: flex; + /* flex container has an extremely-constrained width (and items will + overflow horizontally). This is intentional, as part of stress-testing + item sizing. */ + width: 1px; + } + + .item { + /* We give all flex items a used "flex-basis" of "content" + (from "flex-basis:auto" and default "width:auto"). + We also give them zero flex-grow, flex-shrink, and min-main-size, so + that the flex base size entirely determines the flex item's size. */ + flex: 0 0 auto; + min-width: 0; + border: 2px solid teal; + } + ib { + display: inline-block; + background: blue; + border: 1px solid gray; + width: 15px; + height: 10px; + } + float { + float: left; + background: fuchsia; + border: 1px solid gray; + width: 15px; + height: 10px; + } + canvas { + background: brown; + border: 1px solid gray; + } + .innerFlex { + display: flex; + } + innerItem { + background: salmon; + border: 1px solid gray; + height: 10px; + width: 15px; + flex: none; + } + </style> +</head> +<body> +<!-- The idea of this test is to be sure the UA is using the "max-content" size + (and not e.g. the "fit-content size") when resolving the flex base size + inside each flex container. To differentiate between max-content and + other intrinsic size possibilities (min-content/fit-content), we: + - use flex items with a large difference between its min-content size & + its max-content size (e.g. wrappable content). + - use a very small container (to compress the size, if the UA incorrectly + allows the size to be influenced by the container size). +--> + +<!-- Flex item has several inline-blocks + (no spaces, to avoid any text-layout dependency): --> +<div class="container"> + <div class="item"><ib></ib><ib></ib><ib></ib></div> +</div> + +<!-- Flex item has several floats: --> +<div class="container"> + <div class="item"> + <float></float> + <float></float> + <float></float> + </div> +</div> + +<!-- Flex item has several inline replaced elements: + (no spaces, to avoid any text-layout dependency): --> +<div class="container"> + <div class="item"> + <canvas width="15" height="10"></canvas + ><canvas width="15" height="10"></canvas + ><canvas width="15" height="10"></canvas> + </div> +</div> + +<!-- Flex item *is* a replaced element: --> +<div class="container"> + <canvas class="item" width="25" height="10"></canvas> +</div> + +<!-- Flex item is itself a flex container: --> +<div class="container"> + <div class="item innerFlex"> + <innerItem></innerItem> + <innerItem></innerItem> + <innerItem></innerItem> + </div> +</div> + +<!-- Flex item is itself a multi-line flex container: --> +<div class="container"> + <div class="item innerFlex" style="flex-wrap: wrap"> + <innerItem></innerItem> + <innerItem></innerItem> + <innerItem></innerItem> + </div> +</div> + +</body> +</html> diff --git a/layout/reftests/w3c-css/submitted/flexbox/flexbox-flex-basis-content-004-ref.html b/layout/reftests/w3c-css/submitted/flexbox/flexbox-flex-basis-content-004-ref.html new file mode 100644 index 0000000000..7da4de7a5a --- /dev/null +++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-flex-basis-content-004-ref.html @@ -0,0 +1,105 @@ +<!DOCTYPE html> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<html> +<head> + <title>CSS Reftest Reference</title> + <meta charset="utf-8"> + <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com"> + <style> + .container { + clear: both; /* In this reference case, we use floats instead of + flex items (see below), so the container just + needs to reset the float state for each example. */ + height: 50px; + } + + .item { + border: 2px solid teal; + float: left; /* Use floated elements as a reference for (hopefully) + max-content sized flex items in testcase. */ + } + ib { + display: inline-block; + background: blue; + border: 1px solid gray; + width: 15px; + height: 10px; + } + float { + float: left; + background: fuchsia; + border: 1px solid gray; + width: 15px; + height: 10px; + } + canvas { + background: brown; + border: 1px solid gray; + } + .innerFlex { + display: flex; + flex-direction: column; + } + innerItem { + background: salmon; + border: 1px solid gray; + height: 10px; + width: 15px; + flex: none; + } + </style> +</head> +<body> +<!-- In testcase, flex item has several inline-blocks + (no spaces, to avoid any text-layout dependency): --> +<div class="container"> + <div class="item"><ib></ib><ib></ib><ib></ib></div> +</div> + +<!-- In testcase, flex item has several floats: --> +<div class="container"> + <div class="item"> + <float></float> + <float></float> + <float></float> + </div> +</div> + +<!-- In testcase, flex item has several inline replaced elements: + (no spaces, to avoid any text-layout dependency): --> +<div class="container"> + <div class="item"> + <canvas width="15" height="10"></canvas + ><canvas width="15" height="10"></canvas + ><canvas width="15" height="10"></canvas> + </div> +</div> + +<!-- In testcase, flex item *is* a replaced element: --> +<div class="container"> + <canvas class="item" width="25" height="10"></canvas> +</div> + +<!-- In testcase, flex item is itself a flex container: --> +<div class="container"> + <div class="item innerFlex"> + <innerItem></innerItem> + <innerItem></innerItem> + <innerItem></innerItem> + </div> +</div> + +<!-- In testcase, flex item is itself a multi-line flex container: --> +<div class="container"> + <div class="item innerFlex" style="flex-wrap: wrap"> + <innerItem></innerItem> + <innerItem></innerItem> + <innerItem></innerItem> + </div> +</div> + +</body> +</html> diff --git a/layout/reftests/w3c-css/submitted/flexbox/flexbox-flex-basis-content-004a.html b/layout/reftests/w3c-css/submitted/flexbox/flexbox-flex-basis-content-004a.html new file mode 100644 index 0000000000..65a86b508f --- /dev/null +++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-flex-basis-content-004a.html @@ -0,0 +1,129 @@ +<!DOCTYPE html> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<html> +<head> + <title> + CSS Test: Testing that explicit "flex-basis: content" is treated as + "max-content" when calculating flex base size + </title> + <meta charset="utf-8"> + <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com"> + <link rel="help" href="https://www.w3.org/TR/css-flexbox-1/#flex-base-size"> + <link rel="match" href="flexbox-flex-basis-content-004-ref.html"> + <style> + .container { + display: flex; + flex-direction: column; + align-items: flex-start; + /* flex container has an extremely-constrained height (and items will + overflow vertically). This is intentional, as part of stress-testing + item sizing. We add a large margin-bottom so that overflowing + items don't overlap between examples. */ + height: 1px; + margin-bottom: 49px; + } + + .item { + /* We give all flex items "flex-basis: content". + We also give them zero flex-grow, flex-shrink, and min-main-size, so + that the flex base size entirely determines the flex item's size. */ + flex: 0 0 content; + min-height: 0; + border: 2px solid teal; + } + ib { + display: inline-block; + background: blue; + border: 1px solid gray; + width: 15px; + height: 10px; + } + float { + float: left; + background: fuchsia; + border: 1px solid gray; + width: 15px; + height: 10px; + } + canvas { + background: brown; + border: 1px solid gray; + } + .innerFlex { + display: flex; + flex-direction: column; + } + innerItem { + background: salmon; + border: 1px solid gray; + height: 10px; + width: 15px; + flex: none; + } + </style> +</head> +<body> +<!-- This test exists for symmetry with the previous set of tests + (flexbox-flex-basis-content-003*). Those previous tests check how + "flex-basis:content" is resolved to a flex base size, in the inline axis, + when the container's size is constrained in that axis. This test does the + same, but for the *block* axis, using flex-direction:column. As with the + previous set of tests, the expectation here is that we should use the + item's max-content size as its flex base size. Note that there's a bit + less subtlety here because intrinsic sizes (min-content, max-content) are + typically all the same in the block axis. +--> + +<!-- Flex item has several inline-blocks + (no spaces, to avoid any text-layout dependency): --> +<div class="container"> + <div class="item"><ib></ib><ib></ib><ib></ib></div> +</div> + +<!-- Flex item has several floats: --> +<div class="container"> + <div class="item"> + <float></float> + <float></float> + <float></float> + </div> +</div> + +<!-- Flex item has several inline replaced elements: + (no spaces, to avoid any text-layout dependency): --> +<div class="container"> + <div class="item"> + <canvas width="15" height="10"></canvas + ><canvas width="15" height="10"></canvas + ><canvas width="15" height="10"></canvas> + </div> +</div> + +<!-- Flex item *is* a replaced element: --> +<div class="container"> + <canvas class="item" width="25" height="10"></canvas> +</div> + +<!-- Flex item is itself a flex container: --> +<div class="container"> + <div class="item innerFlex"> + <innerItem></innerItem> + <innerItem></innerItem> + <innerItem></innerItem> + </div> +</div> + +<!-- Flex item is itself a multi-line flex container: --> +<div class="container"> + <div class="item innerFlex" style="flex-wrap: wrap"> + <innerItem></innerItem> + <innerItem></innerItem> + <innerItem></innerItem> + </div> +</div> + +</body> +</html> diff --git a/layout/reftests/w3c-css/submitted/flexbox/flexbox-flex-basis-content-004b.html b/layout/reftests/w3c-css/submitted/flexbox/flexbox-flex-basis-content-004b.html new file mode 100644 index 0000000000..a686f1aa1e --- /dev/null +++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-flex-basis-content-004b.html @@ -0,0 +1,130 @@ +<!DOCTYPE html> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<html> +<head> + <title> + CSS Test: Testing that used "flex-basis: content" is treated as + "max-content" when calculating flex base size + </title> + <meta charset="utf-8"> + <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com"> + <link rel="help" href="https://www.w3.org/TR/css-flexbox-1/#flex-base-size"> + <link rel="match" href="flexbox-flex-basis-content-004-ref.html"> + <style> + .container { + display: flex; + flex-direction: column; + align-items: flex-start; + /* flex container has an extremely-constrained height (and items will + overflow vertically). This is intentional, as part of stress-testing + item sizing. We add a large margin-bottom so that overflowing + items don't overlap between examples. */ + height: 1px; + margin-bottom: 49px; + } + + .item { + /* We give all flex items a used "flex-basis" of "content" + (from "flex-basis:auto" and default "width:auto"). + We also give them zero flex-grow, flex-shrink, and min-main-size, so + that the flex base size entirely determines the flex item's size. */ + flex: 0 0 auto; + min-height: 0; + border: 2px solid teal; + } + ib { + display: inline-block; + background: blue; + border: 1px solid gray; + width: 15px; + height: 10px; + } + float { + float: left; + background: fuchsia; + border: 1px solid gray; + width: 15px; + height: 10px; + } + canvas { + background: brown; + border: 1px solid gray; + } + .innerFlex { + display: flex; + flex-direction: column; + } + innerItem { + background: salmon; + border: 1px solid gray; + height: 10px; + width: 15px; + flex: none; + } + </style> +</head> +<body> +<!-- This test exists for symmetry with the previous set of tests + (flexbox-flex-basis-content-003*). Those previous tests check how + "flex-basis:content" is resolved to a flex base size, in the inline axis, + when the container's size is constrained in that axis. This test does the + same, but for the *block* axis, using flex-direction:column. As with the + previous set of tests, the expectation here is that we should use the + item's max-content size as its flex base size. Note that there's a bit + less subtlety here because intrinsic sizes (min-content, max-content) are + typically all the same in the block axis. +--> + +<!-- Flex item has several inline-blocks + (no spaces, to avoid any text-layout dependency): --> +<div class="container"> + <div class="item"><ib></ib><ib></ib><ib></ib></div> +</div> + +<!-- Flex item has several floats: --> +<div class="container"> + <div class="item"> + <float></float> + <float></float> + <float></float> + </div> +</div> + +<!-- Flex item has several inline replaced elements: + (no spaces, to avoid any text-layout dependency): --> +<div class="container"> + <div class="item"> + <canvas width="15" height="10"></canvas + ><canvas width="15" height="10"></canvas + ><canvas width="15" height="10"></canvas> + </div> +</div> + +<!-- Flex item *is* a replaced element: --> +<div class="container"> + <canvas class="item" width="25" height="10"></canvas> +</div> + +<!-- Flex item is itself a flex container: --> +<div class="container"> + <div class="item innerFlex"> + <innerItem></innerItem> + <innerItem></innerItem> + <innerItem></innerItem> + </div> +</div> + +<!-- Flex item is itself a multi-line flex container: --> +<div class="container"> + <div class="item innerFlex" style="flex-wrap: wrap"> + <innerItem></innerItem> + <innerItem></innerItem> + <innerItem></innerItem> + </div> +</div> + +</body> +</html> diff --git a/layout/reftests/w3c-css/submitted/flexbox/reftest.list b/layout/reftests/w3c-css/submitted/flexbox/reftest.list index 075aa660e1..7cac455ae0 100644 --- a/layout/reftests/w3c-css/submitted/flexbox/reftest.list +++ b/layout/reftests/w3c-css/submitted/flexbox/reftest.list @@ -98,6 +98,16 @@ == flexbox-column-row-gap-004.html flexbox-column-row-gap-004-ref.html == flexbox-gap-position-absolute.html flexbox-gap-position-absolute-ref.html +# Tests for "flex-basis: content" +== flexbox-flex-basis-content-001a.html flexbox-flex-basis-content-001-ref.html +== flexbox-flex-basis-content-001b.html flexbox-flex-basis-content-001-ref.html +== flexbox-flex-basis-content-002a.html flexbox-flex-basis-content-002-ref.html +== flexbox-flex-basis-content-002b.html flexbox-flex-basis-content-002-ref.html +== flexbox-flex-basis-content-003a.html flexbox-flex-basis-content-003-ref.html +== flexbox-flex-basis-content-003b.html flexbox-flex-basis-content-003-ref.html +== flexbox-flex-basis-content-004a.html flexbox-flex-basis-content-004-ref.html +== flexbox-flex-basis-content-004b.html flexbox-flex-basis-content-004-ref.html + # Tests for flex-flow shorthand property == flexbox-flex-flow-001.html flexbox-flex-flow-001-ref.html == flexbox-flex-flow-002.html flexbox-flex-flow-002-ref.html 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 diff --git a/layout/style/test/property_database.js b/layout/style/test/property_database.js index e3e719771b..5c6e2f6d86 100644 --- a/layout/style/test/property_database.js +++ b/layout/style/test/property_database.js @@ -4130,6 +4130,8 @@ var gCSSProperties = { "calc(50px/(2 - 1))", ], invalid_values: [ "none", "-2px", + /* invalid for width but not flex-basis */ + "content", /* invalid -moz-calc() values */ "-moz-calc(50%+ 2px)", "-moz-calc(50% +2px)", @@ -4645,12 +4647,18 @@ var gCSSProperties = { inherited: false, type: CSS_TYPE_LONGHAND, initial_values: [ " auto" ], - // NOTE: This is cribbed directly from the "width" chunk, since this - // property takes the exact same values as width (albeit with - // different semantics on 'auto'). - // XXXdholbert (Maybe these should get separated out into - // a reusable array defined at the top of this file?) - other_values: [ "15px", "3em", "15%", "-moz-max-content", "-moz-min-content", "-moz-fit-content", "-moz-available", + // NOTE: Besides "content", this is cribbed directly from the "width" + // chunk, since this property takes the exact same values as width + // (plus 'content' & with different semantics on 'auto'). + other_values: [ + "15px", + "3em", + "15%", + "-moz-max-content", + "-moz-min-content", + "-moz-fit-content", + "-moz-available", + "content", // valid calc() values "calc(-2px)", "calc(2px)", |