From a8c637281f5f310a6a89e9fb8e47d65e2e08c98c Mon Sep 17 00:00:00 2001 From: Daniel Holbert Date: Thu, 25 Jul 2024 18:18:24 +0000 Subject: [PATCH] Bug 1909773 part 4: Add support for '-webkit-fill-available' as an alias for the CSS 'stretch' behavior (off-by-default for now). r=emilio Both '-webkit-fill-available' and 'stretch' are equivalent to '-moz-available' at this point in the patch series, and both are off-by-default, because actually supporting them would require that we add special logic to handle them as block-axis sizes (which I'll do in a separate bug). Differential Revision: https://phabricator.services.mozilla.com/D217687 --- layout/generic/nsIFrame.h | 1 + layout/style/ServoStyleConstsInlines.h | 16 ++++++++-------- layout/style/nsComputedDOMStyle.cpp | 12 +++++++++++- layout/style/test/mochitest.toml | 1 + layout/style/test/property_database.js | 13 +++++++++++++ layout/style/test/test_value_computation.html | 5 +++-- layout/tables/BasicTableLayoutStrategy.cpp | 1 + modules/libpref/init/StaticPrefList.yaml | 7 +++++++ servo/components/style/values/computed/length.rs | 1 + servo/components/style/values/generics/length.rs | 4 ++++ .../components/style/values/specified/length.rs | 6 ++++++ 11 files changed, 56 insertions(+), 11 deletions(-) diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index 9ec22d1d2301..58c28a5f5df6 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -4797,6 +4797,7 @@ class nsIFrame : public nsQueryFrame { return mozilla::Some(ExtremumLength::MaxContent); case SizeOrMaxSize::Tag::MozAvailable: return mozilla::Some(ExtremumLength::MozAvailable); + case SizeOrMaxSize::Tag::WebkitFillAvailable: case SizeOrMaxSize::Tag::Stretch: return mozilla::Some(ExtremumLength::Stretch); case SizeOrMaxSize::Tag::FitContent: diff --git a/layout/style/ServoStyleConstsInlines.h b/layout/style/ServoStyleConstsInlines.h index 6b3fc8cdeb22..38f408ea8306 100644 --- a/layout/style/ServoStyleConstsInlines.h +++ b/layout/style/ServoStyleConstsInlines.h @@ -828,14 +828,14 @@ inline bool StyleFlexBasis::IsAuto() const { return IsSize() && AsSize().IsAuto(); } -#define IMPL_BEHAVES_LIKE_SIZE_METHODS(ty_, isInitialValMethod_) \ - template <> \ - inline bool ty_::BehavesLikeStretchOnInlineAxis() const { \ - return IsStretch() || IsMozAvailable(); \ - } \ - template <> \ - inline bool ty_::BehavesLikeInitialValueOnBlockAxis() const { \ - return isInitialValMethod_() || !IsLengthPercentage(); \ +#define IMPL_BEHAVES_LIKE_SIZE_METHODS(ty_, isInitialValMethod_) \ + template <> \ + inline bool ty_::BehavesLikeStretchOnInlineAxis() const { \ + return IsStretch() || IsMozAvailable() || IsWebkitFillAvailable(); \ + } \ + template <> \ + inline bool ty_::BehavesLikeInitialValueOnBlockAxis() const { \ + return isInitialValMethod_() || !IsLengthPercentage(); \ } IMPL_BEHAVES_LIKE_SIZE_METHODS(StyleSize, IsAuto) diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp index 038ca9738c6e..2e124fc7cbef 100644 --- a/layout/style/nsComputedDOMStyle.cpp +++ b/layout/style/nsComputedDOMStyle.cpp @@ -2113,8 +2113,18 @@ static void SetValueToExtremumLength(nsROCSSPrimitiveValue* aValue, return aValue->SetString("min-content"); case nsIFrame::ExtremumLength::MozAvailable: return aValue->SetString("-moz-available"); - case nsIFrame::ExtremumLength::Stretch: + case nsIFrame::ExtremumLength::Stretch: { + // By default we serialize this value using the standard "stretch" + // keyword. The exception is when that keyword is explicitly preffed off + // and the legacy "-webkit-fill-available" keyword is preffed on; in + // that case, we serialize to the legacy webkit-prefixed alias, to + // ensure that we can round-trip properly. + if (!StaticPrefs::layout_css_stretch_size_keyword_enabled() && + StaticPrefs::layout_css_webkit_fill_available_enabled()) { + return aValue->SetString("-webkit-fill-available"); + } return aValue->SetString("stretch"); + } case nsIFrame::ExtremumLength::FitContent: return aValue->SetString("fit-content"); case nsIFrame::ExtremumLength::FitContentFunction: diff --git a/layout/style/test/mochitest.toml b/layout/style/test/mochitest.toml index 9889ff55f371..ffd05af150cd 100644 --- a/layout/style/test/mochitest.toml +++ b/layout/style/test/mochitest.toml @@ -7,6 +7,7 @@ prefs = [ "layout.css.fit-content-function.enabled=true", "layout.css.scroll-driven-animations.enabled=true", "layout.css.stretch-size-keyword.enabled=true", + "layout.css.webkit-fill-available.enabled=true", "layout.css.animation-composition.enabled=true", "layout.css.basic-shape-rect.enabled=true", "layout.css.basic-shape-shape.enabled=true", diff --git a/layout/style/test/property_database.js b/layout/style/test/property_database.js index a22fbca17223..b052fcadf873 100644 --- a/layout/style/test/property_database.js +++ b/layout/style/test/property_database.js @@ -6290,6 +6290,7 @@ var gCSSProperties = { "-moz-min-content", "-moz-fit-content", "-moz-available", + "-webkit-fill-available", "calc(2px)", "calc(50%)", "calc(3*25px)", @@ -6736,6 +6737,7 @@ var gCSSProperties = { "-moz-min-content", "-moz-fit-content", "-moz-available", + "-webkit-fill-available", "calc(2px)", "calc(-2px)", "calc(0px)", @@ -6768,6 +6770,7 @@ var gCSSProperties = { "-moz-min-content", "-moz-fit-content", "-moz-available", + "-webkit-fill-available", "calc(2px)", "calc(-2px)", "calc(0px)", @@ -6799,6 +6802,7 @@ var gCSSProperties = { "-moz-min-content", "-moz-fit-content", "-moz-available", + "-webkit-fill-available", "calc(-1%)", "calc(2px)", "calc(50%)", @@ -6829,6 +6833,7 @@ var gCSSProperties = { "-moz-min-content", "-moz-fit-content", "-moz-available", + "-webkit-fill-available", "calc(-1%)", "calc(2px)", "calc(50%)", @@ -8823,6 +8828,7 @@ var gCSSProperties = { "-moz-min-content", "-moz-fit-content", "-moz-available", + "-webkit-fill-available", "3e1px", "3e+1px", "3e0px", @@ -10197,6 +10203,7 @@ var gCSSProperties = { "-moz-min-content", "-moz-fit-content", "-moz-available", + "-webkit-fill-available", // valid calc() values "calc(-2px)", "calc(2px)", @@ -10451,6 +10458,7 @@ var gCSSProperties = { "-moz-min-content", "-moz-fit-content", "-moz-available", + "-webkit-fill-available", "calc(2px)", "calc(50%)", "calc(3*25px)", @@ -10802,6 +10810,7 @@ var gCSSProperties = { "-moz-min-content", "-moz-fit-content", "-moz-available", + "-webkit-fill-available", "calc(2px)", "calc(50%)", "calc(3*25px)", @@ -10949,6 +10958,7 @@ var gCSSProperties = { "-moz-min-content", "-moz-fit-content", "-moz-available", + "-webkit-fill-available", "calc(2px)", "calc(50%)", "calc(3*25px)", @@ -10979,6 +10989,7 @@ var gCSSProperties = { "-moz-min-content", "-moz-fit-content", "-moz-available", + "-webkit-fill-available", "calc(2px)", "calc(50%)", "calc(3*25px)", @@ -11009,6 +11020,7 @@ var gCSSProperties = { "-moz-min-content", "-moz-fit-content", "-moz-available", + "-webkit-fill-available", "calc(-1%)", "calc(2px)", "calc(50%)", @@ -11040,6 +11052,7 @@ var gCSSProperties = { "-moz-min-content", "-moz-fit-content", "-moz-available", + "-webkit-fill-available", "calc(-1%)", "calc(2px)", "calc(50%)", diff --git a/layout/style/test/test_value_computation.html b/layout/style/test/test_value_computation.html index be331103fef1..8c98ccdeed5a 100644 --- a/layout/style/test/test_value_computation.html +++ b/layout/style/test/test_value_computation.html @@ -76,13 +76,14 @@ var gSwapInitialWhenHaveFrame = { // For the inline axis ('width' by default): when there's a frame, // 'stretch' and its prefixed aliases work out to the same as 'auto', // given the prerequisites of only 'display: block'. - "width": [ "-moz-available", "stretch" ], + "width": [ "-moz-available", "-webkit-fill-available", "stretch" ], // For the block axis ('height' by default): when there's a frame, these // keywords work out to the same as the initial value, i.e. `auto`, given // the prerequisites of only 'display: block'. "height": [ "-moz-max-content", "-moz-min-content", "-moz-fit-content", - "-moz-available", "max-content", "min-content", "fit-content", + "-moz-available", "-webkit-fill-available", + "max-content", "min-content", "fit-content", "fit-content(100px)", "fit-content(10%)", "fit-content(calc(3*25px + 50%))", "stretch" ], }; diff --git a/layout/tables/BasicTableLayoutStrategy.cpp b/layout/tables/BasicTableLayoutStrategy.cpp index 3fb080dbb560..a9516901bfcb 100644 --- a/layout/tables/BasicTableLayoutStrategy.cpp +++ b/layout/tables/BasicTableLayoutStrategy.cpp @@ -139,6 +139,7 @@ static CellISizeInfo GetISizeInfo(gfxContext* aRenderingContext, prefCoord = minCoord; break; case StyleSize::Tag::MozAvailable: + case StyleSize::Tag::WebkitFillAvailable: case StyleSize::Tag::Stretch: case StyleSize::Tag::FitContent: case StyleSize::Tag::FitContentFunction: diff --git a/modules/libpref/init/StaticPrefList.yaml b/modules/libpref/init/StaticPrefList.yaml index 09f6c5a67a0b..8bc249f05b81 100644 --- a/modules/libpref/init/StaticPrefList.yaml +++ b/modules/libpref/init/StaticPrefList.yaml @@ -9739,6 +9739,13 @@ mirror: always rust: true +# Is the '-webkit-fill-available' keyword enabled, as an alias for 'stretch'? +- name: layout.css.webkit-fill-available.enabled + type: RelaxedAtomicBool + value: false + mirror: always + rust: true + # Is support for -webkit-line-clamp on regular blocks enabled? - name: layout.css.webkit-line-clamp.block.enabled type: bool diff --git a/servo/components/style/values/computed/length.rs b/servo/components/style/values/computed/length.rs index 37516f695dfc..e85bf23c388f 100644 --- a/servo/components/style/values/computed/length.rs +++ b/servo/components/style/values/computed/length.rs @@ -209,6 +209,7 @@ impl Size { Self::MaxContent | Self::FitContent | Self::MozAvailable | + Self::WebkitFillAvailable | Self::Stretch | Self::FitContentFunction(_) => false, } diff --git a/servo/components/style/values/generics/length.rs b/servo/components/style/values/generics/length.rs index 939ad7fc0f1c..ba20601d1aab 100644 --- a/servo/components/style/values/generics/length.rs +++ b/servo/components/style/values/generics/length.rs @@ -160,6 +160,8 @@ pub enum GenericSize { #[animation(error)] MozAvailable, #[animation(error)] + WebkitFillAvailable, + #[animation(error)] Stretch, #[animation(error)] #[css(function = "fit-content")] @@ -213,6 +215,8 @@ pub enum GenericMaxSize { #[animation(error)] MozAvailable, #[animation(error)] + WebkitFillAvailable, + #[animation(error)] Stretch, #[animation(error)] #[css(function = "fit-content")] diff --git a/servo/components/style/values/specified/length.rs b/servo/components/style/values/specified/length.rs index ed93968ad9c2..058bb6627748 100644 --- a/servo/components/style/values/specified/length.rs +++ b/servo/components/style/values/specified/length.rs @@ -1954,6 +1954,8 @@ macro_rules! parse_size_non_length { #[cfg(feature = "gecko")] "-moz-available" => $size::MozAvailable, #[cfg(feature = "gecko")] + "-webkit-fill-available" if is_webkit_fill_available_keyword_enabled() => $size::WebkitFillAvailable, + #[cfg(feature = "gecko")] "stretch" if is_stretch_enabled() => $size::Stretch, $auto_or_none => $size::$auto_or_none_ident, }) @@ -1964,6 +1966,10 @@ macro_rules! parse_size_non_length { }}; } +#[cfg(feature = "gecko")] +fn is_webkit_fill_available_keyword_enabled() -> bool { + static_prefs::pref!("layout.css.webkit-fill-available.enabled") +} #[cfg(feature = "gecko")] fn is_stretch_enabled() -> bool { static_prefs::pref!("layout.css.stretch-size-keyword.enabled")