Skip to content

Commit

Permalink
LibWeb: Implement text-align: match-parent
Browse files Browse the repository at this point in the history
At computed-value time, this is converted to whatever the parent's
computed value is. So it behaves a little like `inherit`, except that
an inherited start/end value uses the parent's start/end, which might
be different from the child's.
  • Loading branch information
AtkinsSJ committed Feb 5, 2025
1 parent 4f85528 commit 070c4a2
Show file tree
Hide file tree
Showing 8 changed files with 154 additions and 3 deletions.
1 change: 1 addition & 0 deletions Libraries/LibWeb/CSS/Enums.json
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,7 @@
"end",
"left",
"right",
"match-parent",
"-libweb-center",
"-libweb-left",
"-libweb-right"
Expand Down
5 changes: 3 additions & 2 deletions Libraries/LibWeb/CSS/Keywords.json
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@
"jis04",
"jis78",
"jis83",
"jis90",
"jis90",
"jump-both",
"jump-end",
"jump-none",
Expand Down Expand Up @@ -267,6 +267,7 @@
"luminosity",
"mark",
"marktext",
"match-parent",
"math",
"math-auto",
"max-content",
Expand All @@ -289,7 +290,7 @@
"nearest",
"nesw-resize",
"no-close-quote",
"no-common-ligatures",
"no-common-ligatures",
"no-contextual",
"no-discretionary-ligatures",
"no-drop",
Expand Down
47 changes: 46 additions & 1 deletion Libraries/LibWeb/CSS/StyleComputer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2213,6 +2213,50 @@ void StyleComputer::resolve_effective_overflow_values(ComputedProperties& style)
}
}

static void compute_text_align(ComputedProperties& style, DOM::Element const& element, Optional<Selector::PseudoElement::Type> pseudo_element)
{
// https://drafts.csswg.org/css-text-4/#valdef-text-align-match-parent
// This value behaves the same as inherit (computes to its parent’s computed value) except that an inherited
// value of start or end is interpreted against the parent’s direction value and results in a computed value of
// either left or right. Computes to start when specified on the root element.
if (style.property(PropertyID::TextAlign).to_keyword() == Keyword::MatchParent) {

// If it's a pseudo-element, then the "parent" is the originating element instead.
auto const* parent = [&]() -> DOM::Element const* {
if (pseudo_element.has_value())
return &element;
return element.parent_element();
}();

if (parent) {
auto const& parent_text_align = parent->computed_properties()->property(PropertyID::TextAlign);
auto const& parent_direction = parent->computed_properties()->direction().value_or(Direction::Ltr);
switch (parent_text_align.to_keyword()) {
case Keyword::Start:
if (parent_direction == Direction::Ltr) {
style.set_property(PropertyID::TextAlign, CSSKeywordValue::create(Keyword::Left));
} else {
style.set_property(PropertyID::TextAlign, CSSKeywordValue::create(Keyword::Right));
}
break;

case Keyword::End:
if (parent_direction == Direction::Ltr) {
style.set_property(PropertyID::TextAlign, CSSKeywordValue::create(Keyword::Right));
} else {
style.set_property(PropertyID::TextAlign, CSSKeywordValue::create(Keyword::Left));
}
break;

default:
style.set_property(PropertyID::TextAlign, parent_text_align);
}
} else {
style.set_property(PropertyID::TextAlign, CSSKeywordValue::create(Keyword::Start));
}
}
}

enum class BoxTypeTransformation {
None,
Blockify,
Expand Down Expand Up @@ -2544,8 +2588,9 @@ GC::Ref<ComputedProperties> StyleComputer::compute_properties(DOM::Element& elem
// 6. Run automatic box type transformations
transform_box_type_if_needed(computed_style, element, pseudo_element);

// 7. Resolve effective overflow values
// 7. Apply any property-specific computed value logic
resolve_effective_overflow_values(computed_style);
compute_text_align(computed_style, element, pseudo_element);

// 8. Let the element adjust computed style
element.adjust_computed_style(computed_style);
Expand Down
3 changes: 3 additions & 0 deletions Libraries/LibWeb/Layout/LineBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,9 @@ void LineBuilder::update_last_line()
case CSS::TextAlign::LibwebRight:
inline_offset += excess_inline_space;
break;
case CSS::TextAlign::MatchParent:
// This should have been replaced before this point.
VERIFY_NOT_REACHED();
case CSS::TextAlign::Left:
case CSS::TextAlign::LibwebLeft:
case CSS::TextAlign::Justify:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<!DOCTYPE html>
<head>
<style>
.left { text-align: left; }
.center { text-align: center; }
.right { text-align: right; }
</style>
</head>
<body>
<div>
<div class="left">Left</div>
<div class="left">Left</div>
</div>
<div>
<div class="center">Center</div>
<div class="center">Center</div>
</div>
<div>
<div class="right">Right</div>
<div class="right">Right</div>
</div>
<div>
<div class="right">Right</div>
<div class="right">Right</div>
</div>
<div>
<div class="center">Center</div>
<div class="center">Center</div>
</div>
<div>
<div class="left">Left</div>
<div class="left">Left</div>
</div>
</body>
38 changes: 38 additions & 0 deletions Tests/LibWeb/Ref/input/css/css-text/text-align-match-parent.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<!DOCTYPE html>
<head>
<link rel="match" href="../../../expected/css/css-text/text-align-match-parent-ref.html" />
<style>
.outer-start { text-align: start; }
.outer-end { text-align: end; }
.outer-center { text-align: center; }
.ltr { direction: ltr; }
.rtl { direction: rtl; }
.inner { text-align: match-parent; }
</style>
</head>
<body>
<div class="outer-start ltr">
<div class="inner ltr">Left</div>
<div class="inner rtl">Left</div>
</div>
<div class="outer-center ltr">
<div class="inner ltr">Center</div>
<div class="inner rtl">Center</div>
</div>
<div class="outer-end ltr">
<div class="inner ltr">Right</div>
<div class="inner rtl">Right</div>
</div>
<div class="outer-start rtl">
<div class="inner ltr">Right</div>
<div class="inner rtl">Right</div>
</div>
<div class="outer-center rtl">
<div class="inner ltr">Center</div>
<div class="inner rtl">Center</div>
</div>
<div class="outer-end rtl">
<div class="inner ltr">Left</div>
<div class="inner rtl">Left</div>
</div>
</body>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Harness status: OK

Found 1 tests

1 Pass
Pass CSS Text Test: text-align - computed value for match-parent on the root element
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Text Test: text-align - computed value for match-parent on the root element</title>
<link rel="help" href="https://drafts.csswg.org/css-text/#valdef-text-align-match-parent">
<meta name="assert" content="'text-align: match-parent' on the root element with 'direction: rtl' should compute to 'start'.">
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<style>
html {
text-align: match-parent;
direction: rtl;
}
#log {
direction: ltr;
text-align: start;
}
</style>
<div id="log"></div>
<script>
test(() => {
assert_equals(getComputedStyle(document.documentElement).textAlign, 'start');
});
</script>

0 comments on commit 070c4a2

Please sign in to comment.