mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-12-07 21:59:54 +00:00
LibWeb: Parse and propagate extended text-indent property values
CSS Text 3 gives `text-indent` a couple of optional keywords to control which lines are affected. This commit parses them, but doesn't yet do anything with them.
This commit is contained in:
parent
eea1d4e1d2
commit
c4b9e7eadf
Notes:
github-actions[bot]
2025-11-20 15:03:53 +00:00
Author: https://github.com/AtkinsSJ
Commit: c4b9e7eadf
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/6855
Reviewed-by: https://github.com/gmta ✅
16 changed files with 199 additions and 9 deletions
|
|
@ -273,6 +273,7 @@ set(SOURCES
|
||||||
CSS/StyleValues/StyleValue.cpp
|
CSS/StyleValues/StyleValue.cpp
|
||||||
CSS/StyleValues/StyleValueList.cpp
|
CSS/StyleValues/StyleValueList.cpp
|
||||||
CSS/StyleValues/SuperellipseStyleValue.cpp
|
CSS/StyleValues/SuperellipseStyleValue.cpp
|
||||||
|
CSS/StyleValues/TextIndentStyleValue.cpp
|
||||||
CSS/StyleValues/TextUnderlinePositionStyleValue.cpp
|
CSS/StyleValues/TextUnderlinePositionStyleValue.cpp
|
||||||
CSS/StyleValues/TransformationStyleValue.cpp
|
CSS/StyleValues/TransformationStyleValue.cpp
|
||||||
CSS/StyleValues/TreeCountingFunctionStyleValue.cpp
|
CSS/StyleValues/TreeCountingFunctionStyleValue.cpp
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@
|
||||||
#include <LibWeb/CSS/StyleValues/ShadowStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/ShadowStyleValue.h>
|
||||||
#include <LibWeb/CSS/StyleValues/StringStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/StringStyleValue.h>
|
||||||
#include <LibWeb/CSS/StyleValues/StyleValueList.h>
|
#include <LibWeb/CSS/StyleValues/StyleValueList.h>
|
||||||
|
#include <LibWeb/CSS/StyleValues/TextIndentStyleValue.h>
|
||||||
#include <LibWeb/CSS/StyleValues/TextUnderlinePositionStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/TextUnderlinePositionStyleValue.h>
|
||||||
#include <LibWeb/CSS/StyleValues/TimeStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/TimeStyleValue.h>
|
||||||
#include <LibWeb/CSS/StyleValues/TransformationStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/TransformationStyleValue.h>
|
||||||
|
|
@ -1369,6 +1370,17 @@ Vector<ShadowData> ComputedProperties::text_shadow(Layout::Node const& layout_no
|
||||||
return shadow(PropertyID::TextShadow, layout_node);
|
return shadow(PropertyID::TextShadow, layout_node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TextIndentData ComputedProperties::text_indent() const
|
||||||
|
{
|
||||||
|
auto const& value = property(PropertyID::TextIndent).as_text_indent();
|
||||||
|
|
||||||
|
return TextIndentData {
|
||||||
|
.length_percentage = LengthPercentage::from_style_value(value.length_percentage()),
|
||||||
|
.each_line = value.each_line(),
|
||||||
|
.hanging = value.hanging(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
TextWrapMode ComputedProperties::text_wrap_mode() const
|
TextWrapMode ComputedProperties::text_wrap_mode() const
|
||||||
{
|
{
|
||||||
auto const& value = property(PropertyID::TextWrapMode);
|
auto const& value = property(PropertyID::TextWrapMode);
|
||||||
|
|
|
||||||
|
|
@ -122,6 +122,7 @@ public:
|
||||||
TextDecorationThickness text_decoration_thickness() const;
|
TextDecorationThickness text_decoration_thickness() const;
|
||||||
TextTransform text_transform() const;
|
TextTransform text_transform() const;
|
||||||
Vector<ShadowData> text_shadow(Layout::Node const&) const;
|
Vector<ShadowData> text_shadow(Layout::Node const&) const;
|
||||||
|
TextIndentData text_indent() const;
|
||||||
TextWrapMode text_wrap_mode() const;
|
TextWrapMode text_wrap_mode() const;
|
||||||
ListStyleType list_style_type() const;
|
ListStyleType list_style_type() const;
|
||||||
ListStylePosition list_style_position() const;
|
ListStylePosition list_style_position() const;
|
||||||
|
|
|
||||||
|
|
@ -94,6 +94,12 @@ struct ScrollbarColorData {
|
||||||
Color track_color { Color::Transparent };
|
Color track_color { Color::Transparent };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct TextIndentData {
|
||||||
|
LengthPercentage length_percentage;
|
||||||
|
bool each_line { false };
|
||||||
|
bool hanging { false };
|
||||||
|
};
|
||||||
|
|
||||||
struct TextUnderlinePosition {
|
struct TextUnderlinePosition {
|
||||||
TextUnderlinePositionHorizontal horizontal { TextUnderlinePositionHorizontal::Auto };
|
TextUnderlinePositionHorizontal horizontal { TextUnderlinePositionHorizontal::Auto };
|
||||||
TextUnderlinePositionVertical vertical { TextUnderlinePositionVertical::Auto };
|
TextUnderlinePositionVertical vertical { TextUnderlinePositionVertical::Auto };
|
||||||
|
|
@ -159,7 +165,7 @@ public:
|
||||||
static TextDecorationStyle text_decoration_style() { return TextDecorationStyle::Solid; }
|
static TextDecorationStyle text_decoration_style() { return TextDecorationStyle::Solid; }
|
||||||
static TextTransform text_transform() { return TextTransform::None; }
|
static TextTransform text_transform() { return TextTransform::None; }
|
||||||
static TextOverflow text_overflow() { return TextOverflow::Clip; }
|
static TextOverflow text_overflow() { return TextOverflow::Clip; }
|
||||||
static LengthPercentage text_indent() { return Length::make_px(0); }
|
static TextIndentData text_indent() { return { Length::make_px(0) }; }
|
||||||
static TextWrapMode text_wrap_mode() { return TextWrapMode::Wrap; }
|
static TextWrapMode text_wrap_mode() { return TextWrapMode::Wrap; }
|
||||||
static CSSPixels text_underline_offset() { return 2; }
|
static CSSPixels text_underline_offset() { return 2; }
|
||||||
static TextUnderlinePosition text_underline_position() { return { .horizontal = TextUnderlinePositionHorizontal::Auto, .vertical = TextUnderlinePositionVertical::Auto }; }
|
static TextUnderlinePosition text_underline_position() { return { .horizontal = TextUnderlinePositionHorizontal::Auto, .vertical = TextUnderlinePositionVertical::Auto }; }
|
||||||
|
|
@ -497,7 +503,7 @@ public:
|
||||||
Variant<Length, double> tab_size() const { return m_inherited.tab_size; }
|
Variant<Length, double> tab_size() const { return m_inherited.tab_size; }
|
||||||
TextAlign text_align() const { return m_inherited.text_align; }
|
TextAlign text_align() const { return m_inherited.text_align; }
|
||||||
TextJustify text_justify() const { return m_inherited.text_justify; }
|
TextJustify text_justify() const { return m_inherited.text_justify; }
|
||||||
LengthPercentage const& text_indent() const { return m_inherited.text_indent; }
|
TextIndentData const& text_indent() const { return m_inherited.text_indent; }
|
||||||
TextWrapMode text_wrap_mode() const { return m_inherited.text_wrap_mode; }
|
TextWrapMode text_wrap_mode() const { return m_inherited.text_wrap_mode; }
|
||||||
CSSPixels text_underline_offset() const { return m_inherited.text_underline_offset; }
|
CSSPixels text_underline_offset() const { return m_inherited.text_underline_offset; }
|
||||||
TextUnderlinePosition text_underline_position() const { return m_inherited.text_underline_position; }
|
TextUnderlinePosition text_underline_position() const { return m_inherited.text_underline_position; }
|
||||||
|
|
@ -702,7 +708,7 @@ protected:
|
||||||
TextAlign text_align { InitialValues::text_align() };
|
TextAlign text_align { InitialValues::text_align() };
|
||||||
TextJustify text_justify { InitialValues::text_justify() };
|
TextJustify text_justify { InitialValues::text_justify() };
|
||||||
TextTransform text_transform { InitialValues::text_transform() };
|
TextTransform text_transform { InitialValues::text_transform() };
|
||||||
LengthPercentage text_indent { InitialValues::text_indent() };
|
TextIndentData text_indent { InitialValues::text_indent() };
|
||||||
TextWrapMode text_wrap_mode { InitialValues::text_wrap_mode() };
|
TextWrapMode text_wrap_mode { InitialValues::text_wrap_mode() };
|
||||||
CSSPixels text_underline_offset { InitialValues::text_underline_offset() };
|
CSSPixels text_underline_offset { InitialValues::text_underline_offset() };
|
||||||
TextUnderlinePosition text_underline_position { InitialValues::text_underline_position() };
|
TextUnderlinePosition text_underline_position { InitialValues::text_underline_position() };
|
||||||
|
|
@ -915,7 +921,7 @@ public:
|
||||||
void set_text_decoration_color(Color value) { m_noninherited.text_decoration_color = value; }
|
void set_text_decoration_color(Color value) { m_noninherited.text_decoration_color = value; }
|
||||||
void set_text_transform(TextTransform value) { m_inherited.text_transform = value; }
|
void set_text_transform(TextTransform value) { m_inherited.text_transform = value; }
|
||||||
void set_text_shadow(Vector<ShadowData>&& value) { m_inherited.text_shadow = move(value); }
|
void set_text_shadow(Vector<ShadowData>&& value) { m_inherited.text_shadow = move(value); }
|
||||||
void set_text_indent(LengthPercentage value) { m_inherited.text_indent = move(value); }
|
void set_text_indent(TextIndentData value) { m_inherited.text_indent = move(value); }
|
||||||
void set_text_wrap_mode(TextWrapMode value) { m_inherited.text_wrap_mode = value; }
|
void set_text_wrap_mode(TextWrapMode value) { m_inherited.text_wrap_mode = value; }
|
||||||
void set_text_overflow(TextOverflow value) { m_noninherited.text_overflow = value; }
|
void set_text_overflow(TextOverflow value) { m_noninherited.text_overflow = value; }
|
||||||
void set_text_underline_offset(CSSPixels value) { m_inherited.text_underline_offset = value; }
|
void set_text_underline_offset(CSSPixels value) { m_inherited.text_underline_offset = value; }
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@
|
||||||
#include <LibWeb/CSS/StyleValues/RectStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/RectStyleValue.h>
|
||||||
#include <LibWeb/CSS/StyleValues/StyleValueList.h>
|
#include <LibWeb/CSS/StyleValues/StyleValueList.h>
|
||||||
#include <LibWeb/CSS/StyleValues/SuperellipseStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/SuperellipseStyleValue.h>
|
||||||
|
#include <LibWeb/CSS/StyleValues/TextIndentStyleValue.h>
|
||||||
#include <LibWeb/CSS/StyleValues/TimeStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/TimeStyleValue.h>
|
||||||
#include <LibWeb/CSS/StyleValues/TransformationStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/TransformationStyleValue.h>
|
||||||
#include <LibWeb/CSS/Transformation.h>
|
#include <LibWeb/CSS/Transformation.h>
|
||||||
|
|
@ -1877,6 +1878,22 @@ static RefPtr<StyleValue const> interpolate_value_impl(DOM::Element& element, Ca
|
||||||
interpolate_length_or_auto(from_rect.left_edge, to_rect.left_edge, calculation_context, delta),
|
interpolate_length_or_auto(from_rect.left_edge, to_rect.left_edge, calculation_context, delta),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
case StyleValue::Type::TextIndent: {
|
||||||
|
auto& from_text_indent = from.as_text_indent();
|
||||||
|
auto& to_text_indent = to.as_text_indent();
|
||||||
|
|
||||||
|
if (from_text_indent.each_line() != to_text_indent.each_line()
|
||||||
|
|| from_text_indent.hanging() != to_text_indent.hanging())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
auto interpolated_length_percentage = interpolate_value(element, calculation_context, from_text_indent.length_percentage(), to_text_indent.length_percentage(), delta, allow_discrete);
|
||||||
|
if (!interpolated_length_percentage)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
return TextIndentStyleValue::create(interpolated_length_percentage.release_nonnull(),
|
||||||
|
from_text_indent.hanging() ? TextIndentStyleValue::Hanging::Yes : TextIndentStyleValue::Hanging::No,
|
||||||
|
from_text_indent.each_line() ? TextIndentStyleValue::EachLine::Yes : TextIndentStyleValue::EachLine::No);
|
||||||
|
}
|
||||||
case StyleValue::Type::Superellipse: {
|
case StyleValue::Type::Superellipse: {
|
||||||
// https://drafts.csswg.org/css-borders-4/#corner-shape-interpolation
|
// https://drafts.csswg.org/css-borders-4/#corner-shape-interpolation
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -187,6 +187,7 @@
|
||||||
"down",
|
"down",
|
||||||
"e",
|
"e",
|
||||||
"e-resize",
|
"e-resize",
|
||||||
|
"each-line",
|
||||||
"ease",
|
"ease",
|
||||||
"ease-in",
|
"ease-in",
|
||||||
"ease-in-out",
|
"ease-in-out",
|
||||||
|
|
@ -237,6 +238,7 @@
|
||||||
"graytext",
|
"graytext",
|
||||||
"grid",
|
"grid",
|
||||||
"groove",
|
"groove",
|
||||||
|
"hanging",
|
||||||
"hard-light",
|
"hard-light",
|
||||||
"height",
|
"height",
|
||||||
"help",
|
"help",
|
||||||
|
|
|
||||||
|
|
@ -506,6 +506,7 @@ private:
|
||||||
RefPtr<StyleValue const> parse_shape_outside_value(TokenStream<ComponentValue>&);
|
RefPtr<StyleValue const> parse_shape_outside_value(TokenStream<ComponentValue>&);
|
||||||
RefPtr<StyleValue const> parse_text_decoration_value(TokenStream<ComponentValue>&);
|
RefPtr<StyleValue const> parse_text_decoration_value(TokenStream<ComponentValue>&);
|
||||||
RefPtr<StyleValue const> parse_text_decoration_line_value(TokenStream<ComponentValue>&);
|
RefPtr<StyleValue const> parse_text_decoration_line_value(TokenStream<ComponentValue>&);
|
||||||
|
RefPtr<StyleValue const> parse_text_indent_value(TokenStream<ComponentValue>&);
|
||||||
RefPtr<StyleValue const> parse_text_underline_position_value(TokenStream<ComponentValue>&);
|
RefPtr<StyleValue const> parse_text_underline_position_value(TokenStream<ComponentValue>&);
|
||||||
RefPtr<StyleValue const> parse_rotate_value(TokenStream<ComponentValue>&);
|
RefPtr<StyleValue const> parse_rotate_value(TokenStream<ComponentValue>&);
|
||||||
RefPtr<StyleValue const> parse_stroke_dasharray_value(TokenStream<ComponentValue>&);
|
RefPtr<StyleValue const> parse_stroke_dasharray_value(TokenStream<ComponentValue>&);
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,7 @@
|
||||||
#include <LibWeb/CSS/StyleValues/StringStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/StringStyleValue.h>
|
||||||
#include <LibWeb/CSS/StyleValues/StyleValue.h>
|
#include <LibWeb/CSS/StyleValues/StyleValue.h>
|
||||||
#include <LibWeb/CSS/StyleValues/StyleValueList.h>
|
#include <LibWeb/CSS/StyleValues/StyleValueList.h>
|
||||||
|
#include <LibWeb/CSS/StyleValues/TextIndentStyleValue.h>
|
||||||
#include <LibWeb/CSS/StyleValues/TextUnderlinePositionStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/TextUnderlinePositionStyleValue.h>
|
||||||
#include <LibWeb/CSS/StyleValues/TimeStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/TimeStyleValue.h>
|
||||||
#include <LibWeb/CSS/StyleValues/TransformationStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/TransformationStyleValue.h>
|
||||||
|
|
@ -721,6 +722,8 @@ Parser::ParseErrorOr<NonnullRefPtr<StyleValue const>> Parser::parse_css_value(Pr
|
||||||
return parse_all_as(tokens, [this](auto& tokens) { return parse_text_decoration_value(tokens); });
|
return parse_all_as(tokens, [this](auto& tokens) { return parse_text_decoration_value(tokens); });
|
||||||
case PropertyID::TextDecorationLine:
|
case PropertyID::TextDecorationLine:
|
||||||
return parse_all_as(tokens, [this](auto& tokens) { return parse_text_decoration_line_value(tokens); });
|
return parse_all_as(tokens, [this](auto& tokens) { return parse_text_decoration_line_value(tokens); });
|
||||||
|
case PropertyID::TextIndent:
|
||||||
|
return parse_all_as(tokens, [this](auto& tokens) { return parse_text_indent_value(tokens); });
|
||||||
case PropertyID::TextShadow:
|
case PropertyID::TextShadow:
|
||||||
return parse_all_as(tokens, [this](auto& tokens) { return parse_shadow_value(tokens, ShadowStyleValue::ShadowType::Text); });
|
return parse_all_as(tokens, [this](auto& tokens) { return parse_shadow_value(tokens, ShadowStyleValue::ShadowType::Text); });
|
||||||
case PropertyID::TextUnderlinePosition:
|
case PropertyID::TextUnderlinePosition:
|
||||||
|
|
@ -4731,6 +4734,51 @@ RefPtr<StyleValue const> Parser::parse_text_decoration_line_value(TokenStream<Co
|
||||||
return StyleValueList::create(move(style_values), StyleValueList::Separator::Space);
|
return StyleValueList::create(move(style_values), StyleValueList::Separator::Space);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://drafts.csswg.org/css-text-3/#text-indent-property
|
||||||
|
RefPtr<StyleValue const> Parser::parse_text_indent_value(TokenStream<ComponentValue>& tokens)
|
||||||
|
{
|
||||||
|
// [ <length-percentage> ] && hanging? && each-line?
|
||||||
|
auto transaction = tokens.begin_transaction();
|
||||||
|
|
||||||
|
RefPtr<StyleValue const> length_percentage;
|
||||||
|
bool has_hanging = false;
|
||||||
|
bool has_each_line = false;
|
||||||
|
|
||||||
|
tokens.discard_whitespace();
|
||||||
|
|
||||||
|
while (tokens.has_next_token()) {
|
||||||
|
if (!length_percentage) {
|
||||||
|
if (auto parsed = parse_length_percentage_value(tokens)) {
|
||||||
|
length_percentage = parsed.release_nonnull();
|
||||||
|
tokens.discard_whitespace();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auto keyword = parse_keyword_value(tokens)) {
|
||||||
|
if (!has_hanging && keyword->to_keyword() == Keyword::Hanging) {
|
||||||
|
has_hanging = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!has_each_line && keyword->to_keyword() == Keyword::EachLine) {
|
||||||
|
has_each_line = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!length_percentage)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
transaction.commit();
|
||||||
|
return TextIndentStyleValue::create(length_percentage.release_nonnull(),
|
||||||
|
has_hanging ? TextIndentStyleValue::Hanging::Yes : TextIndentStyleValue::Hanging::No,
|
||||||
|
has_each_line ? TextIndentStyleValue::EachLine::Yes : TextIndentStyleValue::EachLine::No);
|
||||||
|
}
|
||||||
|
|
||||||
// https://drafts.csswg.org/css-text-decor-4/#text-underline-position-property
|
// https://drafts.csswg.org/css-text-decor-4/#text-underline-position-property
|
||||||
RefPtr<StyleValue const> Parser::parse_text_underline_position_value(TokenStream<ComponentValue>& tokens)
|
RefPtr<StyleValue const> Parser::parse_text_underline_position_value(TokenStream<ComponentValue>& tokens)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -3680,6 +3680,10 @@
|
||||||
"length [-∞,∞]",
|
"length [-∞,∞]",
|
||||||
"percentage [-∞,∞]"
|
"percentage [-∞,∞]"
|
||||||
],
|
],
|
||||||
|
"valid-identifiers": [
|
||||||
|
"each-line",
|
||||||
|
"hanging"
|
||||||
|
],
|
||||||
"percentages-resolve-to": "length",
|
"percentages-resolve-to": "length",
|
||||||
"quirks": [
|
"quirks": [
|
||||||
"unitless-length"
|
"unitless-length"
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@
|
||||||
|
|
||||||
#include <LibGfx/Font/Font.h>
|
#include <LibGfx/Font/Font.h>
|
||||||
#include <LibGfx/Font/FontStyleMapping.h>
|
#include <LibGfx/Font/FontStyleMapping.h>
|
||||||
#include <LibGfx/Font/FontWeight.h>
|
|
||||||
#include <LibWeb/CSS/CSSStyleValue.h>
|
#include <LibWeb/CSS/CSSStyleValue.h>
|
||||||
#include <LibWeb/CSS/ComputedProperties.h>
|
#include <LibWeb/CSS/ComputedProperties.h>
|
||||||
#include <LibWeb/CSS/Parser/Parser.h>
|
#include <LibWeb/CSS/Parser/Parser.h>
|
||||||
|
|
@ -68,6 +67,7 @@
|
||||||
#include <LibWeb/CSS/StyleValues/StyleValue.h>
|
#include <LibWeb/CSS/StyleValues/StyleValue.h>
|
||||||
#include <LibWeb/CSS/StyleValues/StyleValueList.h>
|
#include <LibWeb/CSS/StyleValues/StyleValueList.h>
|
||||||
#include <LibWeb/CSS/StyleValues/SuperellipseStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/SuperellipseStyleValue.h>
|
||||||
|
#include <LibWeb/CSS/StyleValues/TextIndentStyleValue.h>
|
||||||
#include <LibWeb/CSS/StyleValues/TextUnderlinePositionStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/TextUnderlinePositionStyleValue.h>
|
||||||
#include <LibWeb/CSS/StyleValues/TimeStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/TimeStyleValue.h>
|
||||||
#include <LibWeb/CSS/StyleValues/TransformationStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/TransformationStyleValue.h>
|
||||||
|
|
|
||||||
|
|
@ -83,6 +83,7 @@ namespace Web::CSS {
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Shorthand, shorthand, ShorthandStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Shorthand, shorthand, ShorthandStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(String, string, StringStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(String, string, StringStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Superellipse, superellipse, SuperellipseStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Superellipse, superellipse, SuperellipseStyleValue) \
|
||||||
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(TextIndent, text_indent, TextIndentStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(TextUnderlinePosition, text_underline_position, TextUnderlinePositionStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(TextUnderlinePosition, text_underline_position, TextUnderlinePositionStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Time, time, TimeStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Time, time, TimeStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Transformation, transformation, TransformationStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Transformation, transformation, TransformationStyleValue) \
|
||||||
|
|
|
||||||
54
Libraries/LibWeb/CSS/StyleValues/TextIndentStyleValue.cpp
Normal file
54
Libraries/LibWeb/CSS/StyleValues/TextIndentStyleValue.cpp
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Sam Atkins <sam@ladybird.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "TextIndentStyleValue.h"
|
||||||
|
|
||||||
|
namespace Web::CSS {
|
||||||
|
|
||||||
|
ValueComparingNonnullRefPtr<TextIndentStyleValue const> TextIndentStyleValue::create(NonnullRefPtr<StyleValue const> length_percentage, Hanging hanging, EachLine each_line)
|
||||||
|
{
|
||||||
|
return adopt_ref(*new (nothrow) TextIndentStyleValue(move(length_percentage), hanging, each_line));
|
||||||
|
}
|
||||||
|
|
||||||
|
TextIndentStyleValue::TextIndentStyleValue(NonnullRefPtr<StyleValue const> length_percentage, Hanging hanging, EachLine each_line)
|
||||||
|
: StyleValueWithDefaultOperators(Type::TextIndent)
|
||||||
|
, m_length_percentage(move(length_percentage))
|
||||||
|
, m_hanging(hanging == Hanging::Yes)
|
||||||
|
, m_each_line(each_line == EachLine::Yes)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
TextIndentStyleValue::~TextIndentStyleValue() = default;
|
||||||
|
|
||||||
|
String TextIndentStyleValue::to_string(SerializationMode mode) const
|
||||||
|
{
|
||||||
|
StringBuilder builder;
|
||||||
|
builder.append(m_length_percentage->to_string(mode));
|
||||||
|
if (m_each_line)
|
||||||
|
builder.append(" each-line"sv);
|
||||||
|
if (m_hanging)
|
||||||
|
builder.append(" hanging"sv);
|
||||||
|
return builder.to_string_without_validation();
|
||||||
|
}
|
||||||
|
|
||||||
|
ValueComparingNonnullRefPtr<StyleValue const> TextIndentStyleValue::absolutized(ComputationContext const& context) const
|
||||||
|
{
|
||||||
|
auto new_length_percentage = m_length_percentage->absolutized(context);
|
||||||
|
if (new_length_percentage->equals(m_length_percentage))
|
||||||
|
return *this;
|
||||||
|
return create(move(new_length_percentage),
|
||||||
|
m_hanging ? Hanging::Yes : Hanging::No,
|
||||||
|
m_each_line ? EachLine::Yes : EachLine::No);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TextIndentStyleValue::properties_equal(TextIndentStyleValue const& other) const
|
||||||
|
{
|
||||||
|
return m_length_percentage == other.m_length_percentage
|
||||||
|
&& m_each_line == other.m_each_line
|
||||||
|
&& m_hanging == other.m_hanging;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
43
Libraries/LibWeb/CSS/StyleValues/TextIndentStyleValue.h
Normal file
43
Libraries/LibWeb/CSS/StyleValues/TextIndentStyleValue.h
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Sam Atkins <sam@ladybird.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <LibWeb/CSS/StyleValues/StyleValue.h>
|
||||||
|
|
||||||
|
namespace Web::CSS {
|
||||||
|
|
||||||
|
class TextIndentStyleValue : public StyleValueWithDefaultOperators<TextIndentStyleValue> {
|
||||||
|
public:
|
||||||
|
enum class Hanging : u8 {
|
||||||
|
No,
|
||||||
|
Yes,
|
||||||
|
};
|
||||||
|
enum class EachLine : u8 {
|
||||||
|
No,
|
||||||
|
Yes,
|
||||||
|
};
|
||||||
|
|
||||||
|
static ValueComparingNonnullRefPtr<TextIndentStyleValue const> create(NonnullRefPtr<StyleValue const> length_percentage, Hanging hanging, EachLine each_line);
|
||||||
|
virtual ~TextIndentStyleValue() override;
|
||||||
|
|
||||||
|
StyleValue const& length_percentage() const { return m_length_percentage; }
|
||||||
|
bool hanging() const { return m_hanging; }
|
||||||
|
bool each_line() const { return m_each_line; }
|
||||||
|
|
||||||
|
virtual String to_string(SerializationMode) const override;
|
||||||
|
virtual ValueComparingNonnullRefPtr<StyleValue const> absolutized(ComputationContext const&) const override;
|
||||||
|
bool properties_equal(TextIndentStyleValue const&) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
TextIndentStyleValue(NonnullRefPtr<StyleValue const> length_percentage, Hanging hanging, EachLine each_line);
|
||||||
|
|
||||||
|
NonnullRefPtr<StyleValue const> m_length_percentage;
|
||||||
|
bool m_hanging;
|
||||||
|
bool m_each_line;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -378,6 +378,7 @@ class StyleValueList;
|
||||||
class SuperellipseStyleValue;
|
class SuperellipseStyleValue;
|
||||||
class Supports;
|
class Supports;
|
||||||
class SVGPaint;
|
class SVGPaint;
|
||||||
|
class TextIndentStyleValue;
|
||||||
class TextUnderlinePositionStyleValue;
|
class TextUnderlinePositionStyleValue;
|
||||||
class Time;
|
class Time;
|
||||||
class TimeOrCalculated;
|
class TimeOrCalculated;
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,8 @@ LineBuilder::LineBuilder(InlineFormattingContext& context, LayoutState& layout_s
|
||||||
, m_direction(direction)
|
, m_direction(direction)
|
||||||
, m_writing_mode(writing_mode)
|
, m_writing_mode(writing_mode)
|
||||||
{
|
{
|
||||||
m_text_indent = m_context.containing_block().computed_values().text_indent().to_px(m_context.containing_block(), m_containing_block_used_values.content_width());
|
auto text_indent = m_context.containing_block().computed_values().text_indent();
|
||||||
|
m_text_indent = text_indent.length_percentage.to_px(m_context.containing_block(), m_containing_block_used_values.content_width());
|
||||||
begin_new_line(false);
|
begin_new_line(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -622,9 +622,7 @@ void NodeWithStyle::apply_style(CSS::ComputedProperties const& computed_style)
|
||||||
computed_values.set_text_underline_offset(computed_style.text_underline_offset());
|
computed_values.set_text_underline_offset(computed_style.text_underline_offset());
|
||||||
computed_values.set_text_underline_position(computed_style.text_underline_position());
|
computed_values.set_text_underline_position(computed_style.text_underline_position());
|
||||||
|
|
||||||
if (auto text_indent = computed_style.length_percentage(CSS::PropertyID::TextIndent, *this, CSS::ComputedProperties::ClampNegativeLengths::No); text_indent.has_value())
|
computed_values.set_text_indent(computed_style.text_indent());
|
||||||
computed_values.set_text_indent(text_indent.release_value());
|
|
||||||
|
|
||||||
computed_values.set_text_wrap_mode(computed_style.text_wrap_mode());
|
computed_values.set_text_wrap_mode(computed_style.text_wrap_mode());
|
||||||
computed_values.set_tab_size(computed_style.tab_size());
|
computed_values.set_tab_size(computed_style.tab_size());
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue