mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-21 20:15:17 +00:00
LibWeb: Implement text-align: match-parent
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.
This commit is contained in:
parent
4f855286d7
commit
070c4a2045
Notes:
github-actions[bot]
2025-02-05 17:46:38 +00:00
Author: https://github.com/AtkinsSJ Commit: https://github.com/LadybirdBrowser/ladybird/commit/070c4a20450 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/3441
8 changed files with 154 additions and 3 deletions
|
@ -523,6 +523,7 @@
|
|||
"end",
|
||||
"left",
|
||||
"right",
|
||||
"match-parent",
|
||||
"-libweb-center",
|
||||
"-libweb-left",
|
||||
"-libweb-right"
|
||||
|
|
|
@ -234,7 +234,7 @@
|
|||
"jis04",
|
||||
"jis78",
|
||||
"jis83",
|
||||
"jis90",
|
||||
"jis90",
|
||||
"jump-both",
|
||||
"jump-end",
|
||||
"jump-none",
|
||||
|
@ -267,6 +267,7 @@
|
|||
"luminosity",
|
||||
"mark",
|
||||
"marktext",
|
||||
"match-parent",
|
||||
"math",
|
||||
"math-auto",
|
||||
"max-content",
|
||||
|
@ -289,7 +290,7 @@
|
|||
"nearest",
|
||||
"nesw-resize",
|
||||
"no-close-quote",
|
||||
"no-common-ligatures",
|
||||
"no-common-ligatures",
|
||||
"no-contextual",
|
||||
"no-discretionary-ligatures",
|
||||
"no-drop",
|
||||
|
|
|
@ -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,
|
||||
|
@ -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);
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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>
|
|
@ -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>
|
|
@ -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
|
|
@ -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>
|
Loading…
Add table
Reference in a new issue