Skip to content

Commit

Permalink
Container query with font units should invalidate when font changes
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=253940
rdar://106739736

Reviewed by Tim Nguyen.

* LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/font-relative-calc-dynamic-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/css/css-contain/container-queries/font-relative-units-dynamic-expected.txt:

The remaining failures are units we don't support.

* Source/WebCore/style/StyleTreeResolver.cpp:
(WebCore::Style::styleChangeAffectsRelativeUnits):

Factor into a function.

(WebCore::Style::TreeResolver::resolveElement):
(WebCore::Style::TreeResolver::updateStateForQueryContainer):

If the container font size changes we need to evaluate all descendants in case there are container queries that use
font-relative units.

* Source/WebCore/style/StyleTreeResolver.h:

Canonical link: https://commits.webkit.org/267258@main
  • Loading branch information
anttijk committed Aug 25, 2023
1 parent 8f95bb7 commit 0b06dbb
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 12 deletions.
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@

FAIL font-relative calc() is responsive to container font-size changes assert_equals: expected "rgb(0, 128, 0)" but got "rgb(255, 0, 0)"
PASS font-relative calc() is responsive to container font-size changes

Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@

FAIL em units respond to changes assert_equals: expected "rgb(0, 128, 0)" but got "rgb(255, 0, 0)"
PASS em units respond to changes
PASS rem units respond to changes
FAIL ex units respond to changes assert_equals: expected "rgb(0, 128, 0)" but got "rgb(255, 0, 0)"
PASS ex units respond to changes
FAIL rex units respond to changes assert_equals: expected "rgb(0, 128, 0)" but got "rgb(255, 0, 0)"
FAIL ch units respond to changes assert_equals: expected "rgb(0, 128, 0)" but got "rgb(255, 0, 0)"
PASS ch units respond to changes
FAIL cap units respond to changes assert_equals: expected "rgb(0, 128, 0)" but got "rgb(255, 0, 0)"
FAIL rch units respond to changes assert_equals: expected "rgb(0, 128, 0)" but got "rgb(255, 0, 0)"
FAIL lh units respond to changes assert_equals: expected "rgb(0, 128, 0)" but got "rgb(255, 0, 0)"
PASS lh units respond to changes
PASS rlh units respond to changes
FAIL ic units respond to changes assert_equals: expected "rgb(0, 128, 0)" but got "rgb(255, 0, 0)"
PASS ic units respond to changes
FAIL ric units respond to changes assert_equals: expected "rgb(0, 128, 0)" but got "rgb(255, 0, 0)"
FAIL rcap units respond to changes assert_equals: expected "rgb(0, 128, 0)" but got "rgb(255, 0, 0)"

20 changes: 15 additions & 5 deletions Source/WebCore/style/StyleTreeResolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,13 @@ auto TreeResolver::computeDescendantsToResolve(Change change, Validity validity,
return DescendantsToResolve::None;
};

static bool styleChangeAffectsRelativeUnits(const RenderStyle& style, const RenderStyle* existingStyle)
{
if (!existingStyle)
return true;
return style.computedFontSize() != existingStyle->computedFontSize();
}

auto TreeResolver::resolveElement(Element& element, const RenderStyle* existingStyle, ResolutionType resolutionType) -> std::pair<ElementUpdate, DescendantsToResolve>
{
if (m_didSeePendingStylesheet && !element.renderOrDisplayContentsStyle() && !m_document.isIgnoringPendingStylesheets()) {
Expand All @@ -233,7 +240,7 @@ auto TreeResolver::resolveElement(Element& element, const RenderStyle* existingS
auto descendantsToResolve = computeDescendantsToResolve(update.change, element.styleValidity(), parent().descendantsToResolve);

if (&element == m_document.documentElement()) {
if (!existingStyle || existingStyle->computedFontSize() != update.style->computedFontSize()) {
if (styleChangeAffectsRelativeUnits(*update.style, existingStyle)) {
// "rem" units are relative to the document element's font size so we need to recompute everything.
scope().resolver->invalidateMatchedDeclarationsCache();
descendantsToResolve = DescendantsToResolve::All;
Expand Down Expand Up @@ -858,7 +865,6 @@ void TreeResolver::resolveComposedTree()

auto change = Change::None;
auto descendantsToResolve = DescendantsToResolve::None;
auto previousContainerType = style ? style->containerType() : ContainerType::Normal;

auto resolutionType = determineResolutionType(element, style, parent.descendantsToResolve, parent.change);
if (resolutionType) {
Expand Down Expand Up @@ -889,7 +895,7 @@ void TreeResolver::resolveComposedTree()
if (!style)
resetStyleForNonRenderedDescendants(element);

auto queryContainerAction = updateStateForQueryContainer(element, style, previousContainerType, change, descendantsToResolve);
auto queryContainerAction = updateStateForQueryContainer(element, style, change, descendantsToResolve);

bool shouldIterateChildren = [&] {
// display::none, no need to resolve descendants.
Expand Down Expand Up @@ -937,7 +943,7 @@ const RenderStyle* TreeResolver::existingStyle(const Element& element)
return style;
}

auto TreeResolver::updateStateForQueryContainer(Element& element, const RenderStyle* style, ContainerType previousContainerType, Change& change, DescendantsToResolve& descendantsToResolve) -> QueryContainerAction
auto TreeResolver::updateStateForQueryContainer(Element& element, const RenderStyle* style, Change& change, DescendantsToResolve& descendantsToResolve) -> QueryContainerAction
{
if (!style)
return QueryContainerAction::None;
Expand All @@ -955,7 +961,11 @@ auto TreeResolver::updateStateForQueryContainer(Element& element, const RenderSt
return QueryContainerAction::Continue;
}

if (style->containerType() != ContainerType::Normal || previousContainerType != ContainerType::Normal) {
auto* existingStyle = element.renderOrDisplayContentsStyle();
if (style->containerType() != ContainerType::Normal || (existingStyle && existingStyle->containerType() != ContainerType::Normal)) {
// If any of the queries use font-size relative units then a font size change may affect their evaluation.
if (styleChangeAffectsRelativeUnits(*style, existingStyle))
descendantsToResolve = DescendantsToResolve::All;
m_queryContainerStates.add(element, QueryContainerState { change, descendantsToResolve });
m_hasUnresolvedQueryContainers = true;
return QueryContainerAction::Resolve;
Expand Down
2 changes: 1 addition & 1 deletion Source/WebCore/style/StyleTreeResolver.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ class TreeResolver {
enum class QueryContainerAction : uint8_t { None, Resolve, Continue };
enum class DescendantsToResolve : uint8_t { None, ChildrenWithExplicitInherit, Children, All };

QueryContainerAction updateStateForQueryContainer(Element&, const RenderStyle*, ContainerType previousContainerType, Change&, DescendantsToResolve&);
QueryContainerAction updateStateForQueryContainer(Element&, const RenderStyle*, Change&, DescendantsToResolve&);

std::pair<ElementUpdate, DescendantsToResolve> resolveElement(Element&, const RenderStyle* existingStyle, ResolutionType);

Expand Down

0 comments on commit 0b06dbb

Please sign in to comment.