diff --git a/third_party/blink/renderer/core/animation/view_timeline.cc b/third_party/blink/renderer/core/animation/view_timeline.cc index f4d84c4633d6e..56c4616e2cf63 100644 --- a/third_party/blink/renderer/core/animation/view_timeline.cc +++ b/third_party/blink/renderer/core/animation/view_timeline.cc @@ -159,11 +159,14 @@ Length InsetValueToLength(const CSSValue* inset_value, if (inset_value->IsPrimitiveValue()) { ElementResolveContext element_resolve_context(*subject); Document& document = subject->GetDocument(); + // Flags can be ignored, because we re-resolve any value that's not px or + // percentage, see IsStyleDependent. + CSSToLengthConversionData::Flags ignored_flags = 0; CSSToLengthConversionData length_conversion_data( subject->GetComputedStyle(), element_resolve_context.ParentStyle(), element_resolve_context.RootElementStyle(), document.GetLayoutView(), CSSToLengthConversionData::ContainerSizes(subject), - subject->GetComputedStyle()->EffectiveZoom()); + subject->GetComputedStyle()->EffectiveZoom(), ignored_flags); return DynamicTo(inset_value) ->ConvertToLength(length_conversion_data); diff --git a/third_party/blink/renderer/core/css/css_gradient_value.cc b/third_party/blink/renderer/core/css/css_gradient_value.cc index 273d0b589d8ae..1064d2b73888f 100644 --- a/third_party/blink/renderer/core/css/css_gradient_value.cc +++ b/third_party/blink/renderer/core/css/css_gradient_value.cc @@ -135,9 +135,12 @@ scoped_refptr CSSGradientValue::GetImage( // We need to create an image. const ComputedStyle* root_style = document.documentElement()->GetComputedStyle(); + + // TODO(crbug.com/947377): Conversion is not supposed to happen here. + CSSToLengthConversionData::Flags ignored_flags = 0; CSSToLengthConversionData conversion_data( &style, &style, root_style, document.GetLayoutView(), container_sizes, - style.EffectiveZoom()); + style.EffectiveZoom(), ignored_flags); scoped_refptr gradient; switch (GetClassType()) { diff --git a/third_party/blink/renderer/core/css/css_math_expression_node_test.cc b/third_party/blink/renderer/core/css/css_math_expression_node_test.cc index 34ea20495ee9b..6c846701dc80c 100644 --- a/third_party/blink/renderer/core/css/css_math_expression_node_test.cc +++ b/third_party/blink/renderer/core/css/css_math_expression_node_test.cc @@ -94,9 +94,11 @@ TEST(CSSCalculationValue, AccumulatePixelsAndPercent) { ComputedStyleBuilder builder(*ComputedStyle::CreateInitialStyleSingleton()); builder.SetEffectiveZoom(5); scoped_refptr style = builder.TakeStyle(); + CSSToLengthConversionData::Flags ignored_flags = 0; CSSToLengthConversionData conversion_data( style.get(), style.get(), style.get(), nullptr, - CSSToLengthConversionData::ContainerSizes(), style->EffectiveZoom()); + CSSToLengthConversionData::ContainerSizes(), style->EffectiveZoom(), + ignored_flags); TestAccumulatePixelsAndPercent( conversion_data, diff --git a/third_party/blink/renderer/core/css/css_to_length_conversion_data.cc b/third_party/blink/renderer/core/css/css_to_length_conversion_data.cc index de70ebad75658..4f013b1ee3740 100644 --- a/third_party/blink/renderer/core/css/css_to_length_conversion_data.cc +++ b/third_party/blink/renderer/core/css/css_to_length_conversion_data.cc @@ -60,11 +60,6 @@ absl::optional FindSizeForContainerAxis(PhysicalAxes requested_axis, return evaluator->Height(); } -void SetHasContainerRelativeUnits(const ComputedStyle* style) { - const_cast(style)->SetHasContainerRelativeUnits(); - const_cast(style)->SetDependsOnSizeContainerQueries(true); -} - } // namespace CSSToLengthConversionData::FontSizes::FontSizes(float em, @@ -193,21 +188,21 @@ void CSSToLengthConversionData::ContainerSizes::CacheSizeIfNeeded( } CSSToLengthConversionData::CSSToLengthConversionData( - const ComputedStyle* element_style, WritingMode writing_mode, const FontSizes& font_sizes, const LineHeightSize& line_height_size, const ViewportSize& viewport_size, const ContainerSizes& container_sizes, - float zoom) + float zoom, + Flags& flags) : CSSLengthResolver( ClampTo(zoom, std::numeric_limits::denorm_min())), - style_(element_style), writing_mode_(writing_mode), font_sizes_(font_sizes), line_height_size_(line_height_size), viewport_size_(viewport_size), - container_sizes_(container_sizes) {} + container_sizes_(container_sizes), + flags_(&flags) {} CSSToLengthConversionData::CSSToLengthConversionData( const ComputedStyle* element_style, @@ -215,114 +210,95 @@ CSSToLengthConversionData::CSSToLengthConversionData( const ComputedStyle* root_style, const LayoutView* layout_view, const ContainerSizes& container_sizes, - float zoom) + float zoom, + Flags& flags) : CSSToLengthConversionData( - element_style, element_style->GetWritingMode(), FontSizes(element_style, root_style), LineHeightSize(parent_style ? *parent_style : *element_style), ViewportSize(layout_view), container_sizes, - zoom) {} + zoom, + flags) {} float CSSToLengthConversionData::EmFontSize(float zoom) const { - // FIXME: Remove style_ from this class. Plumb viewport and font unit - // information through as output parameters on functions involved in length - // resolution. - if (style_) - const_cast(style_)->SetHasEmUnits(); + SetFlag(Flag::kEm); return font_sizes_.Em(zoom); } float CSSToLengthConversionData::RemFontSize(float zoom) const { - if (style_) - const_cast(style_)->SetHasRemUnits(); + SetFlag(Flag::kRem); return font_sizes_.Rem(zoom); } float CSSToLengthConversionData::ExFontSize(float zoom) const { - if (style_) - const_cast(style_)->SetHasGlyphRelativeUnits(); + SetFlag(Flag::kGlyphRelative); return font_sizes_.Ex(zoom); } float CSSToLengthConversionData::ChFontSize(float zoom) const { - if (style_) - const_cast(style_)->SetHasGlyphRelativeUnits(); + SetFlag(Flag::kGlyphRelative); return font_sizes_.Ch(zoom); } float CSSToLengthConversionData::IcFontSize(float zoom) const { - if (style_) - const_cast(style_)->SetHasGlyphRelativeUnits(); + SetFlag(Flag::kGlyphRelative); return font_sizes_.Ic(zoom); } float CSSToLengthConversionData::LineHeight(float zoom) const { - if (style_) { - const_cast(style_)->SetHasGlyphRelativeUnits(); - const_cast(style_)->SetHasLineHeightRelativeUnits(); - } + SetFlag(Flag::kGlyphRelative); + SetFlag(Flag::kLineHeightRelative); return line_height_size_.Lh(zoom); } double CSSToLengthConversionData::ViewportWidth() const { - if (style_) - const_cast(style_)->SetHasStaticViewportUnits(); + SetFlag(Flag::kStaticViewport); return viewport_size_.LargeWidth(); } double CSSToLengthConversionData::ViewportHeight() const { - if (style_) - const_cast(style_)->SetHasStaticViewportUnits(); + SetFlag(Flag::kStaticViewport); return viewport_size_.LargeHeight(); } double CSSToLengthConversionData::SmallViewportWidth() const { - if (style_) - const_cast(style_)->SetHasStaticViewportUnits(); + SetFlag(Flag::kStaticViewport); return viewport_size_.SmallWidth(); } double CSSToLengthConversionData::SmallViewportHeight() const { - if (style_) - const_cast(style_)->SetHasStaticViewportUnits(); + SetFlag(Flag::kStaticViewport); return viewport_size_.SmallHeight(); } double CSSToLengthConversionData::LargeViewportWidth() const { - if (style_) - const_cast(style_)->SetHasStaticViewportUnits(); + SetFlag(Flag::kStaticViewport); return viewport_size_.LargeWidth(); } double CSSToLengthConversionData::LargeViewportHeight() const { - if (style_) - const_cast(style_)->SetHasStaticViewportUnits(); + SetFlag(Flag::kStaticViewport); return viewport_size_.LargeHeight(); } double CSSToLengthConversionData::DynamicViewportWidth() const { - if (style_) - const_cast(style_)->SetHasDynamicViewportUnits(); + SetFlag(Flag::kDynamicViewport); return viewport_size_.DynamicWidth(); } double CSSToLengthConversionData::DynamicViewportHeight() const { - if (style_) - const_cast(style_)->SetHasDynamicViewportUnits(); + SetFlag(Flag::kDynamicViewport); return viewport_size_.DynamicHeight(); } double CSSToLengthConversionData::ContainerWidth() const { - if (style_) - SetHasContainerRelativeUnits(style_); + SetFlag(Flag::kContainerRelative); return container_sizes_.Width().value_or(SmallViewportWidth()); } double CSSToLengthConversionData::ContainerHeight() const { - if (style_) - SetHasContainerRelativeUnits(style_); + SetFlag(Flag::kContainerRelative); return container_sizes_.Height().value_or(SmallViewportHeight()); } @@ -332,7 +308,7 @@ WritingMode CSSToLengthConversionData::GetWritingMode() const { CSSToLengthConversionData::ContainerSizes CSSToLengthConversionData::PreCachedContainerSizesCopy() const { - SetHasContainerRelativeUnits(style_); + SetFlag(Flag::kContainerRelative); return container_sizes_.PreCachedCopy(); } diff --git a/third_party/blink/renderer/core/css/css_to_length_conversion_data.h b/third_party/blink/renderer/core/css/css_to_length_conversion_data.h index fbc1c4a24f821..1697862f9c689 100644 --- a/third_party/blink/renderer/core/css/css_to_length_conversion_data.h +++ b/third_party/blink/renderer/core/css/css_to_length_conversion_data.h @@ -176,20 +176,43 @@ class CORE_EXPORT CSSToLengthConversionData : public CSSLengthResolver { mutable absl::optional cached_height_; }; + using Flags = uint8_t; + + // Flags represent the units seen in a conversion. They are used for targeted + // invalidation, e.g. when root font-size changes, only elements dependent on + // rem units are recalculated. + enum class Flag : Flags { + // em + kEm = 1u << 0, + // rem + kRem = 1u << 1, + // ex, ch, ic, lh + kGlyphRelative = 1u << 2, + // lh + kLineHeightRelative = 1u << 3, + // sv*, lv*, v* + kStaticViewport = 1u << 4, + // dv* + kDynamicViewport = 1u << 5, + // cq* + kContainerRelative = 1u << 6, + }; + CSSToLengthConversionData() : CSSLengthResolver(1 /* zoom */) {} - CSSToLengthConversionData(const ComputedStyle* element_style, - WritingMode, + CSSToLengthConversionData(WritingMode, const FontSizes&, const LineHeightSize&, const ViewportSize&, const ContainerSizes&, - float zoom); + float zoom, + Flags&); CSSToLengthConversionData(const ComputedStyle* element_style, const ComputedStyle* parent_style, const ComputedStyle* root_style, const LayoutView*, const ContainerSizes&, - float zoom); + float zoom, + Flags&); float EmFontSize(float zoom) const override; float RemFontSize(float zoom) const override; @@ -221,21 +244,28 @@ class CORE_EXPORT CSSToLengthConversionData : public CSSLengthResolver { ContainerSizes PreCachedContainerSizesCopy() const; CSSToLengthConversionData CopyWithAdjustedZoom(float new_zoom) const { - return CSSToLengthConversionData(style_, writing_mode_, font_sizes_, + DCHECK(flags_); + return CSSToLengthConversionData(writing_mode_, font_sizes_, line_height_size_, viewport_size_, - container_sizes_, new_zoom); + container_sizes_, new_zoom, *flags_); } CSSToLengthConversionData Unzoomed() const { return CopyWithAdjustedZoom(1.0f); } private: - const ComputedStyle* style_ = nullptr; + void SetFlag(Flag flag) const { + if (flags_) { + *flags_ |= static_cast(flag); + } + } + WritingMode writing_mode_ = WritingMode::kHorizontalTb; FontSizes font_sizes_; LineHeightSize line_height_size_; ViewportSize viewport_size_; ContainerSizes container_sizes_; + mutable Flags* flags_ = nullptr; }; class ScopedCSSToLengthConversionData : public CSSToLengthConversionData { diff --git a/third_party/blink/renderer/core/css/css_to_length_conversion_data_test.cc b/third_party/blink/renderer/core/css/css_to_length_conversion_data_test.cc index 872a22b233153..6f36bf71d41de 100644 --- a/third_party/blink/renderer/core/css/css_to_length_conversion_data_test.cc +++ b/third_party/blink/renderer/core/css/css_to_length_conversion_data_test.cc @@ -29,8 +29,9 @@ class CSSToLengthConversionDataTest : public PageTestBase { // css_zoom - The zoom to apply to :root. // data_zoom - The zoom to pass to the CSSToLengthConversionData constructor. CSSToLengthConversionData ConversionData( - absl::optional css_zoom = absl::nullopt, - absl::optional data_zoom = absl::nullopt) { + absl::optional css_zoom, + absl::optional data_zoom, + CSSToLengthConversionData::Flags& flags) { Element* root = GetDocument().documentElement(); DCHECK(root); if (css_zoom.has_value()) { @@ -50,7 +51,18 @@ class CSSToLengthConversionDataTest : public PageTestBase { GetDocument().documentElement()->GetComputedStyle(), GetDocument().GetLayoutView(), CSSToLengthConversionData::ContainerSizes(), - data_zoom.value_or(div->GetComputedStyle()->EffectiveZoom())); + data_zoom.value_or(div->GetComputedStyle()->EffectiveZoom()), flags); + } + + CSSToLengthConversionData ConversionData( + absl::optional css_zoom = absl::nullopt, + absl::optional data_zoom = absl::nullopt) { + return ConversionData(css_zoom, data_zoom, ignored_flags_); + } + + CSSToLengthConversionData ConversionData( + CSSToLengthConversionData::Flags& flags) { + return ConversionData(absl::nullopt, absl::nullopt, flags); } float Convert(const CSSToLengthConversionData& data, String value) { @@ -60,10 +72,20 @@ class CSSToLengthConversionDataTest : public PageTestBase { return primitive_value->ConvertToLength(data).Pixels(); } + CSSToLengthConversionData::Flags ConversionFlags(String value) { + CSSToLengthConversionData::Flags flags = 0; + CSSToLengthConversionData data = ConversionData(flags); + Convert(data, value); + return flags; + } + void SetLineHeightSize(Element& element, CSSToLengthConversionData& data) { data.SetLineHeightSize( CSSToLengthConversionData::LineHeightSize(element.ComputedStyleRef())); } + + private: + CSSToLengthConversionData::Flags ignored_flags_ = 0; }; TEST_F(CSSToLengthConversionDataTest, Normal) { @@ -141,4 +163,67 @@ TEST_F(CSSToLengthConversionDataTest, SetLineHeightSize) { EXPECT_FLOAT_EQ(20.0f, Convert(data, "1lh")); } +TEST_F(CSSToLengthConversionDataTest, Flags) { + using Flag = CSSToLengthConversionData::Flag; + using Flags = CSSToLengthConversionData::Flags; + + Flags em = static_cast(Flag::kEm); + Flags rem = static_cast(Flag::kRem); + Flags glyph = static_cast(Flag::kGlyphRelative); + Flags lh = static_cast(Flag::kLineHeightRelative); + Flags sv = static_cast(Flag::kStaticViewport); + Flags dv = static_cast(Flag::kDynamicViewport); + Flags cq = static_cast(Flag::kContainerRelative); + + EXPECT_EQ(0u, ConversionFlags("1px")); + + EXPECT_EQ(em, ConversionFlags("1em")); + + EXPECT_EQ(rem, ConversionFlags("1rem")); + + EXPECT_EQ(glyph, ConversionFlags("1ex")); + EXPECT_EQ(glyph, ConversionFlags("1ch")); + EXPECT_EQ(glyph, ConversionFlags("1ic")); + + EXPECT_EQ(glyph | lh, ConversionFlags("1lh")); + + EXPECT_EQ(sv, ConversionFlags("1svw")); + EXPECT_EQ(sv, ConversionFlags("1svh")); + EXPECT_EQ(sv, ConversionFlags("1svi")); + EXPECT_EQ(sv, ConversionFlags("1svb")); + EXPECT_EQ(sv, ConversionFlags("1svmin")); + EXPECT_EQ(sv, ConversionFlags("1svmax")); + + EXPECT_EQ(sv, ConversionFlags("1lvw")); + EXPECT_EQ(sv, ConversionFlags("1lvh")); + EXPECT_EQ(sv, ConversionFlags("1lvi")); + EXPECT_EQ(sv, ConversionFlags("1lvb")); + EXPECT_EQ(sv, ConversionFlags("1lvmin")); + EXPECT_EQ(sv, ConversionFlags("1lvmax")); + + EXPECT_EQ(sv, ConversionFlags("1vw")); + EXPECT_EQ(sv, ConversionFlags("1vh")); + EXPECT_EQ(sv, ConversionFlags("1vi")); + EXPECT_EQ(sv, ConversionFlags("1vb")); + EXPECT_EQ(sv, ConversionFlags("1vmin")); + EXPECT_EQ(sv, ConversionFlags("1vmax")); + + EXPECT_EQ(dv, ConversionFlags("1dvw")); + EXPECT_EQ(dv, ConversionFlags("1dvh")); + EXPECT_EQ(dv, ConversionFlags("1dvi")); + EXPECT_EQ(dv, ConversionFlags("1dvb")); + EXPECT_EQ(dv, ConversionFlags("1dvmin")); + EXPECT_EQ(dv, ConversionFlags("1dvmax")); + + // Since there is no container, these units fall back to the small viewport. + EXPECT_EQ(cq | sv, ConversionFlags("1cqh")); + EXPECT_EQ(cq | sv, ConversionFlags("1cqw")); + EXPECT_EQ(cq | sv, ConversionFlags("1cqi")); + EXPECT_EQ(cq | sv, ConversionFlags("1cqb")); + EXPECT_EQ(cq | sv, ConversionFlags("1cqmin")); + EXPECT_EQ(cq | sv, ConversionFlags("1cqmax")); + + EXPECT_EQ(em | glyph, ConversionFlags("calc(1em + 1ex)")); +} + } // namespace blink diff --git a/third_party/blink/renderer/core/css/parser/sizes_math_function_parser_test.cc b/third_party/blink/renderer/core/css/parser/sizes_math_function_parser_test.cc index c1a7378ac5f35..095187b884dfc 100644 --- a/third_party/blink/renderer/core/css/parser/sizes_math_function_parser_test.cc +++ b/third_party/blink/renderer/core/css/parser/sizes_math_function_parser_test.cc @@ -61,9 +61,10 @@ static void VerifyCSSCalc(String text, CSSToLengthConversionData::ViewportSize viewport_size(viewport_width, viewport_height); CSSToLengthConversionData::ContainerSizes container_sizes; + CSSToLengthConversionData::Flags ignored_flags = 0; CSSToLengthConversionData conversion_data( - nullptr, WritingMode::kHorizontalTb, font_sizes, line_height_size, - viewport_size, container_sizes, 1.0); + WritingMode::kHorizontalTb, font_sizes, line_height_size, viewport_size, + container_sizes, 1.0, ignored_flags); EXPECT_APPROX_EQ(value, math_value->ComputeLength(conversion_data)); } diff --git a/third_party/blink/renderer/core/css/resolver/filter_operation_resolver.cc b/third_party/blink/renderer/core/css/resolver/filter_operation_resolver.cc index 4ef9a36618f11..5ac502149fb00 100644 --- a/third_party/blink/renderer/core/css/resolver/filter_operation_resolver.cc +++ b/third_party/blink/renderer/core/css/resolver/filter_operation_resolver.cc @@ -266,9 +266,10 @@ FilterOperations FilterOperationResolver::CreateOffscreenFilterOperations( CSSToLengthConversionData::LineHeightSize line_height_size; CSSToLengthConversionData::ViewportSize viewport_size(0, 0); CSSToLengthConversionData::ContainerSizes container_sizes; + CSSToLengthConversionData::Flags ignored_flags = 0; CSSToLengthConversionData conversion_data( - nullptr /* element_style */, WritingMode::kHorizontalTb, font_sizes, - line_height_size, viewport_size, container_sizes, 1 /* zoom */); + WritingMode::kHorizontalTb, font_sizes, line_height_size, viewport_size, + container_sizes, 1 /* zoom */, ignored_flags); for (auto& curr_value : To(in_value)) { if (curr_value->IsURIValue()) diff --git a/third_party/blink/renderer/core/css/resolver/font_style_resolver.cc b/third_party/blink/renderer/core/css/resolver/font_style_resolver.cc index 94711af6775d6..2bcf2df7eb77f 100644 --- a/third_party/blink/renderer/core/css/resolver/font_style_resolver.cc +++ b/third_party/blink/renderer/core/css/resolver/font_style_resolver.cc @@ -23,9 +23,10 @@ FontDescription FontStyleResolver::ComputeFont( CSSToLengthConversionData::LineHeightSize line_height_size; CSSToLengthConversionData::ViewportSize viewport_size(0, 0); CSSToLengthConversionData::ContainerSizes container_sizes; - CSSToLengthConversionData conversionData(nullptr, WritingMode::kHorizontalTb, - font_sizes, line_height_size, - viewport_size, container_sizes, 1); + CSSToLengthConversionData::Flags ignored_flags = 0; + CSSToLengthConversionData conversion_data( + WritingMode::kHorizontalTb, font_sizes, line_height_size, viewport_size, + container_sizes, 1, ignored_flags); // CSSPropertyID::kFontSize if (property_set.HasProperty(CSSPropertyID::kFontSize)) { @@ -38,7 +39,7 @@ FontDescription FontStyleResolver::ComputeFont( } else { builder.SetSize(StyleBuilderConverterBase::ConvertFontSize( *property_set.GetPropertyCSSValue(CSSPropertyID::kFontSize), - conversionData, FontDescription::Size(0, 0.0f, false), nullptr)); + conversion_data, FontDescription::Size(0, 0.0f, false), nullptr)); } } diff --git a/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc b/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc index 9e7ba8ceb5bce..baac19732b739 100644 --- a/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc +++ b/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc @@ -1419,7 +1419,7 @@ Length StyleBuilderConverter::ConvertLength( } UnzoomedLength StyleBuilderConverter::ConvertUnzoomedLength( - const StyleResolverState& state, + StyleResolverState& state, const CSSValue& value) { return UnzoomedLength(To(value).ConvertToLength( state.UnzoomedLengthConversionData())); @@ -2390,10 +2390,11 @@ const CSSValue& StyleBuilderConverter::ConvertRegisteredPropertyInitialValue( CSSToLengthConversionData::ViewportSize viewport_size( document.GetLayoutView()); CSSToLengthConversionData::ContainerSizes container_sizes; - CSSToLengthConversionData conversion_data( - /* element_style */ nullptr, WritingMode::kHorizontalTb, font_sizes, - line_height_size, viewport_size, container_sizes, - /* zoom */ 1.0f); + CSSToLengthConversionData::Flags ignored_flags = 0; + CSSToLengthConversionData conversion_data(WritingMode::kHorizontalTb, + font_sizes, line_height_size, + viewport_size, container_sizes, + /* zoom */ 1.0f, ignored_flags); const CSSParserContext* parser_context = document.ElementSheet().Contents()->ParserContext(); diff --git a/third_party/blink/renderer/core/css/resolver/style_builder_converter.h b/third_party/blink/renderer/core/css/resolver/style_builder_converter.h index bd42bde4a24fc..17afea970b7ef 100644 --- a/third_party/blink/renderer/core/css/resolver/style_builder_converter.h +++ b/third_party/blink/renderer/core/css/resolver/style_builder_converter.h @@ -190,7 +190,7 @@ class StyleBuilderConverter { const CSSValue&); static Length ConvertLength(const StyleResolverState&, const CSSValue&); static Length ConvertLength(const StyleResolverState&, const ScopedCSSValue&); - static UnzoomedLength ConvertUnzoomedLength(const StyleResolverState&, + static UnzoomedLength ConvertUnzoomedLength(StyleResolverState&, const CSSValue&); static float ConvertZoom(const StyleResolverState&, const CSSValue&); static Length ConvertLengthOrAuto(const StyleResolverState&, const CSSValue&); diff --git a/third_party/blink/renderer/core/css/resolver/style_resolver.cc b/third_party/blink/renderer/core/css/resolver/style_resolver.cc index 98a4999cbf1f0..bec428c3fe800 100644 --- a/third_party/blink/renderer/core/css/resolver/style_resolver.cc +++ b/third_party/blink/renderer/core/css/resolver/style_resolver.cc @@ -324,6 +324,41 @@ void UseCountLegacyOverlapping(Document& document, } } +void ApplyLengthConversionFlags(StyleResolverState& state) { + using Flags = CSSToLengthConversionData::Flags; + using Flag = CSSToLengthConversionData::Flag; + + Flags flags = state.TakeLengthConversionFlags(); + if (!flags) { + return; + } + + ComputedStyle* style = state.Style(); + + if (flags & static_cast(Flag::kEm)) { + style->SetHasEmUnits(); + } + if (flags & static_cast(Flag::kRem)) { + style->SetHasRemUnits(); + } + if (flags & static_cast(Flag::kGlyphRelative)) { + style->SetHasGlyphRelativeUnits(); + } + if (flags & static_cast(Flag::kLineHeightRelative)) { + style->SetHasLineHeightRelativeUnits(); + } + if (flags & static_cast(Flag::kStaticViewport)) { + style->SetHasStaticViewportUnits(); + } + if (flags & static_cast(Flag::kDynamicViewport)) { + style->SetHasDynamicViewportUnits(); + } + if (flags & static_cast(Flag::kContainerRelative)) { + style->SetDependsOnSizeContainerQueries(true); + style->SetHasContainerRelativeUnits(); + } +} + } // namespace static CSSPropertyValueSet* LeftToRightDeclaration() { @@ -1754,6 +1789,10 @@ bool StyleResolver::ApplyAnimatedStyle(StyleResolverState& state, // Start loading resources used by animations. state.LoadPendingResources(); + // Apply any length conversion flags produced by CSS/Web animations (e.g. + // animations involving viewport units would set such flags). + ApplyLengthConversionFlags(state); + DCHECK(!state.GetFontBuilder().FontDirty()); } @@ -2140,9 +2179,11 @@ void StyleResolver::CascadeAndApplyMatchedProperties(StyleResolverState& state, UseCountLegacyOverlapping(GetDocument(), *non_legacy_style, *state.Style()); } - // NOTE: This flag needs to be set before the entry is added to the - // matched properties cache, or it will be wrong on cache hits. + // NOTE: This flag (and the length conversion flags) need to be set before the + // entry is added to the matched properties cache, or it will be wrong on + // cache hits. state.StyleBuilder().SetInlineStyleLostCascade(cascade.InlineStyleLost()); + ApplyLengthConversionFlags(state); MaybeAddToMatchedPropertiesCache(state, cache_success, result); diff --git a/third_party/blink/renderer/core/css/resolver/style_resolver_state.cc b/third_party/blink/renderer/core/css/resolver/style_resolver_state.cc index fe23d761cd2a0..b6022b52adcc6 100644 --- a/third_party/blink/renderer/core/css/resolver/style_resolver_state.cc +++ b/third_party/blink/renderer/core/css/resolver/style_resolver_state.cc @@ -118,13 +118,13 @@ void StyleResolverState::UpdateLengthConversionData() { css_to_length_conversion_data_ = CSSToLengthConversionData( Style(), ParentStyle(), RootElementStyle(), GetDocument().GetLayoutView(), CSSToLengthConversionData::ContainerSizes(container_unit_context_), - StyleBuilder().EffectiveZoom()); + StyleBuilder().EffectiveZoom(), length_conversion_flags_); element_style_resources_.UpdateLengthConversionData( &css_to_length_conversion_data_); } CSSToLengthConversionData StyleResolverState::UnzoomedLengthConversionData( - const ComputedStyle* font_style) const { + const ComputedStyle* font_style) { float em = font_style->SpecifiedFontSize(); float rem = RootElementStyle() ? RootElementStyle()->SpecifiedFontSize() : 1; CSSToLengthConversionData::FontSizes font_sizes( @@ -136,17 +136,16 @@ CSSToLengthConversionData StyleResolverState::UnzoomedLengthConversionData( CSSToLengthConversionData::ContainerSizes container_sizes( container_unit_context_); - return CSSToLengthConversionData(Style(), StyleBuilder().GetWritingMode(), - font_sizes, line_height_size, viewport_size, - container_sizes, 1); + return CSSToLengthConversionData( + StyleBuilder().GetWritingMode(), font_sizes, line_height_size, + viewport_size, container_sizes, 1, length_conversion_flags_); } -CSSToLengthConversionData StyleResolverState::FontSizeConversionData() const { +CSSToLengthConversionData StyleResolverState::FontSizeConversionData() { return UnzoomedLengthConversionData(ParentStyle()); } -CSSToLengthConversionData StyleResolverState::UnzoomedLengthConversionData() - const { +CSSToLengthConversionData StyleResolverState::UnzoomedLengthConversionData() { return UnzoomedLengthConversionData(Style()); } diff --git a/third_party/blink/renderer/core/css/resolver/style_resolver_state.h b/third_party/blink/renderer/core/css/resolver/style_resolver_state.h index cb5e433fea2c5..600e16f3bbb09 100644 --- a/third_party/blink/renderer/core/css/resolver/style_resolver_state.h +++ b/third_party/blink/renderer/core/css/resolver/style_resolver_state.h @@ -98,8 +98,8 @@ class CORE_EXPORT StyleResolverState { const CSSToLengthConversionData& CssToLengthConversionData() const { return css_to_length_conversion_data_; } - CSSToLengthConversionData FontSizeConversionData() const; - CSSToLengthConversionData UnzoomedLengthConversionData() const; + CSSToLengthConversionData FontSizeConversionData(); + CSSToLengthConversionData UnzoomedLengthConversionData(); ScopedCSSToLengthConversionData GetScopedCSSToLengthConversionData( const TreeScope* scope) const { @@ -107,6 +107,12 @@ class CORE_EXPORT StyleResolverState { scope); } + CSSToLengthConversionData::Flags TakeLengthConversionFlags() { + CSSToLengthConversionData::Flags flags = length_conversion_flags_; + length_conversion_flags_ = 0; + return flags; + } + void SetConversionFontSizes( const CSSToLengthConversionData::FontSizes& font_sizes) { css_to_length_conversion_data_.SetFontSizes(font_sizes); @@ -210,7 +216,7 @@ class CORE_EXPORT StyleResolverState { private: void UpdateLengthConversionData(); CSSToLengthConversionData UnzoomedLengthConversionData( - const ComputedStyle* font_style) const; + const ComputedStyle* font_style); ElementResolveContext element_context_; Document* document_; @@ -218,6 +224,7 @@ class CORE_EXPORT StyleResolverState { // The primary output for each element's style resolve. ComputedStyleBuilder style_builder_; + CSSToLengthConversionData::Flags length_conversion_flags_ = 0; CSSToLengthConversionData css_to_length_conversion_data_; // parent_style_ is not always just ElementResolveContext::ParentStyle(), diff --git a/third_party/blink/renderer/core/css/threaded/css_to_length_conversion_data_threaded_test.cc b/third_party/blink/renderer/core/css/threaded/css_to_length_conversion_data_threaded_test.cc index 11257c5a08b38..156fc5228324b 100644 --- a/third_party/blink/renderer/core/css/threaded/css_to_length_conversion_data_threaded_test.cc +++ b/third_party/blink/renderer/core/css/threaded/css_to_length_conversion_data_threaded_test.cc @@ -22,9 +22,10 @@ TSAN_TEST(CSSToLengthConversionDataThreadedTest, Construction) { CSSToLengthConversionData::LineHeightSize line_height_size; CSSToLengthConversionData::ViewportSize viewport_size(0, 0); CSSToLengthConversionData::ContainerSizes container_sizes; + CSSToLengthConversionData::Flags ignored_flags = 0; CSSToLengthConversionData conversion_data( - nullptr, WritingMode::kHorizontalTb, font_sizes, line_height_size, - viewport_size, container_sizes, 1); + WritingMode::kHorizontalTb, font_sizes, line_height_size, viewport_size, + container_sizes, 1, ignored_flags); }); } @@ -36,9 +37,10 @@ TSAN_TEST(CSSToLengthConversionDataThreadedTest, ConversionEm) { CSSToLengthConversionData::LineHeightSize line_height_size; CSSToLengthConversionData::ViewportSize viewport_size(0, 0); CSSToLengthConversionData::ContainerSizes container_sizes; + CSSToLengthConversionData::Flags ignored_flags = 0; CSSToLengthConversionData conversion_data( - nullptr, WritingMode::kHorizontalTb, font_sizes, line_height_size, - viewport_size, container_sizes, 1); + WritingMode::kHorizontalTb, font_sizes, line_height_size, viewport_size, + container_sizes, 1, ignored_flags); CSSPrimitiveValue& value = *CSSNumericLiteralValue::Create( 3.14, CSSPrimitiveValue::UnitType::kEms); @@ -56,9 +58,10 @@ TSAN_TEST(CSSToLengthConversionDataThreadedTest, ConversionPixel) { CSSToLengthConversionData::LineHeightSize line_height_size; CSSToLengthConversionData::ViewportSize viewport_size(0, 0); CSSToLengthConversionData::ContainerSizes container_sizes; + CSSToLengthConversionData::Flags ignored_flags = 0; CSSToLengthConversionData conversion_data( - nullptr, WritingMode::kHorizontalTb, font_sizes, line_height_size, - viewport_size, container_sizes, 1); + WritingMode::kHorizontalTb, font_sizes, line_height_size, viewport_size, + container_sizes, 1, ignored_flags); CSSPrimitiveValue& value = *CSSNumericLiteralValue::Create( 44, CSSPrimitiveValue::UnitType::kPixels); @@ -76,9 +79,10 @@ TSAN_TEST(CSSToLengthConversionDataThreadedTest, ConversionViewport) { CSSToLengthConversionData::LineHeightSize line_height_size; CSSToLengthConversionData::ViewportSize viewport_size(0, 0); CSSToLengthConversionData::ContainerSizes container_sizes; + CSSToLengthConversionData::Flags ignored_flags = 0; CSSToLengthConversionData conversion_data( - nullptr, WritingMode::kHorizontalTb, font_sizes, line_height_size, - viewport_size, container_sizes, 1); + WritingMode::kHorizontalTb, font_sizes, line_height_size, viewport_size, + container_sizes, 1, ignored_flags); CSSPrimitiveValue& value = *CSSNumericLiteralValue::Create( 1, CSSPrimitiveValue::UnitType::kViewportWidth); @@ -96,9 +100,10 @@ TSAN_TEST(CSSToLengthConversionDataThreadedTest, ConversionRem) { CSSToLengthConversionData::LineHeightSize line_height_size; CSSToLengthConversionData::ViewportSize viewport_size(0, 0); CSSToLengthConversionData::ContainerSizes container_sizes; + CSSToLengthConversionData::Flags ignored_flags = 0; CSSToLengthConversionData conversion_data( - nullptr, WritingMode::kHorizontalTb, font_sizes, line_height_size, - viewport_size, container_sizes, 1); + WritingMode::kHorizontalTb, font_sizes, line_height_size, viewport_size, + container_sizes, 1, ignored_flags); CSSPrimitiveValue& value = *CSSNumericLiteralValue::Create(1, CSSPrimitiveValue::UnitType::kRems); diff --git a/third_party/blink/renderer/core/svg/svg_length_context.cc b/third_party/blink/renderer/core/svg/svg_length_context.cc index abe6a175c3927..761d859f9325b 100644 --- a/third_party/blink/renderer/core/svg/svg_length_context.cc +++ b/third_party/blink/renderer/core/svg/svg_length_context.cc @@ -562,11 +562,12 @@ float SVGLengthContext::ResolveValue(const CSSPrimitiveValue& primitive_value, return 0; DCHECK(context_); + CSSToLengthConversionData::Flags ignored_flags = 0; CSSToLengthConversionData conversion_data = CSSToLengthConversionData( style, style, root_style, context_->GetDocument().GetLayoutView(), CSSToLengthConversionData::ContainerSizes( context_->ParentOrShadowHostElement()), - 1.0f); + 1.0f, ignored_flags); Length length = primitive_value.ConvertToLength(conversion_data); return ValueForLength(length, 1.0f, mode); }