mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-09-21 08:48:57 +00:00
LibWeb: Parse text-underline-position
property
This introduces the `TextUnderlinePositionStyleValue` class, it is possible to represent `text-underline-position` as a `StyleValueList` but would have required ugly workarounds for either serialization or in `ComputedProperties::text_underline_position`
This commit is contained in:
parent
a6812e1005
commit
b0e3af7d10
Notes:
github-actions[bot]
2025-09-15 14:25:30 +00:00
Author: https://github.com/Calme1709
Commit: b0e3af7d10
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/6190
Reviewed-by: https://github.com/AtkinsSJ ✅
21 changed files with 306 additions and 62 deletions
|
@ -260,6 +260,7 @@ set(SOURCES
|
||||||
CSS/StyleValues/ShorthandStyleValue.cpp
|
CSS/StyleValues/ShorthandStyleValue.cpp
|
||||||
CSS/StyleValues/StyleValue.cpp
|
CSS/StyleValues/StyleValue.cpp
|
||||||
CSS/StyleValues/StyleValueList.cpp
|
CSS/StyleValues/StyleValueList.cpp
|
||||||
|
CSS/StyleValues/TextUnderlinePositionStyleValue.cpp
|
||||||
CSS/StyleValues/TransformationStyleValue.cpp
|
CSS/StyleValues/TransformationStyleValue.cpp
|
||||||
CSS/StyleValues/TransitionStyleValue.cpp
|
CSS/StyleValues/TransitionStyleValue.cpp
|
||||||
CSS/StyleValues/UnicodeRangeStyleValue.cpp
|
CSS/StyleValues/UnicodeRangeStyleValue.cpp
|
||||||
|
|
|
@ -716,6 +716,16 @@
|
||||||
"none",
|
"none",
|
||||||
"uppercase"
|
"uppercase"
|
||||||
],
|
],
|
||||||
|
"text-underline-position-horizontal": [
|
||||||
|
"auto",
|
||||||
|
"from-font",
|
||||||
|
"under"
|
||||||
|
],
|
||||||
|
"text-underline-position-vertical": [
|
||||||
|
"auto",
|
||||||
|
"left",
|
||||||
|
"right"
|
||||||
|
],
|
||||||
"text-wrap-mode": [
|
"text-wrap-mode": [
|
||||||
"wrap",
|
"wrap",
|
||||||
"nowrap"
|
"nowrap"
|
||||||
|
|
|
@ -541,6 +541,7 @@
|
||||||
"ui-serif",
|
"ui-serif",
|
||||||
"ultra-condensed",
|
"ultra-condensed",
|
||||||
"ultra-expanded",
|
"ultra-expanded",
|
||||||
|
"under",
|
||||||
"underline",
|
"underline",
|
||||||
"unicase",
|
"unicase",
|
||||||
"unicode",
|
"unicode",
|
||||||
|
|
|
@ -472,6 +472,7 @@ private:
|
||||||
RefPtr<StyleValue const> parse_single_shadow_value(TokenStream<ComponentValue>&, AllowInsetKeyword);
|
RefPtr<StyleValue const> parse_single_shadow_value(TokenStream<ComponentValue>&, AllowInsetKeyword);
|
||||||
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_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>&);
|
||||||
RefPtr<StyleValue const> parse_easing_value(TokenStream<ComponentValue>&);
|
RefPtr<StyleValue const> parse_easing_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/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>
|
||||||
#include <LibWeb/CSS/StyleValues/TransitionStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/TransitionStyleValue.h>
|
||||||
|
@ -749,6 +750,10 @@ Parser::ParseErrorOr<NonnullRefPtr<StyleValue const>> Parser::parse_css_value(Pr
|
||||||
if (auto parsed_value = parse_shadow_value(tokens, AllowInsetKeyword::No); parsed_value && !tokens.has_next_token())
|
if (auto parsed_value = parse_shadow_value(tokens, AllowInsetKeyword::No); parsed_value && !tokens.has_next_token())
|
||||||
return parsed_value.release_nonnull();
|
return parsed_value.release_nonnull();
|
||||||
return ParseError::SyntaxError;
|
return ParseError::SyntaxError;
|
||||||
|
case PropertyID::TextUnderlinePosition:
|
||||||
|
if (auto parsed_value = parse_text_underline_position_value(tokens); parsed_value && !tokens.has_next_token())
|
||||||
|
return parsed_value.release_nonnull();
|
||||||
|
return ParseError::SyntaxError;
|
||||||
case PropertyID::TouchAction:
|
case PropertyID::TouchAction:
|
||||||
if (auto parsed_value = parse_touch_action_value(tokens); parsed_value && !tokens.has_next_token())
|
if (auto parsed_value = parse_touch_action_value(tokens); parsed_value && !tokens.has_next_token())
|
||||||
return parsed_value.release_nonnull();
|
return parsed_value.release_nonnull();
|
||||||
|
@ -4283,6 +4288,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-decor-4/#text-underline-position-property
|
||||||
|
RefPtr<StyleValue const> Parser::parse_text_underline_position_value(TokenStream<ComponentValue>& tokens)
|
||||||
|
{
|
||||||
|
// auto | [ from-font | under ] || [ left | right ]
|
||||||
|
auto transaction = tokens.begin_transaction();
|
||||||
|
|
||||||
|
if (parse_all_as_single_keyword_value(tokens, Keyword::Auto)) {
|
||||||
|
transaction.commit();
|
||||||
|
return TextUnderlinePositionStyleValue::create(TextUnderlinePositionHorizontal::Auto, TextUnderlinePositionVertical::Auto);
|
||||||
|
}
|
||||||
|
|
||||||
|
Optional<TextUnderlinePositionHorizontal> horizontal_value;
|
||||||
|
Optional<TextUnderlinePositionVertical> vertical_value;
|
||||||
|
|
||||||
|
while (tokens.has_next_token()) {
|
||||||
|
auto keyword_value = parse_keyword_value(tokens);
|
||||||
|
|
||||||
|
if (!keyword_value)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
if (auto maybe_horizontal_value = keyword_to_text_underline_position_horizontal(keyword_value->to_keyword()); maybe_horizontal_value.has_value()) {
|
||||||
|
if (maybe_horizontal_value == TextUnderlinePositionHorizontal::Auto || horizontal_value.has_value())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
horizontal_value = maybe_horizontal_value;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auto maybe_vertical_value = keyword_to_text_underline_position_vertical(keyword_value->to_keyword()); maybe_vertical_value.has_value()) {
|
||||||
|
if (maybe_vertical_value == TextUnderlinePositionVertical::Auto || vertical_value.has_value())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
vertical_value = maybe_vertical_value;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
transaction.commit();
|
||||||
|
return TextUnderlinePositionStyleValue::create(horizontal_value.value_or(TextUnderlinePositionHorizontal::Auto), vertical_value.value_or(TextUnderlinePositionVertical::Auto));
|
||||||
|
}
|
||||||
|
|
||||||
// https://www.w3.org/TR/pointerevents/#the-touch-action-css-property
|
// https://www.w3.org/TR/pointerevents/#the-touch-action-css-property
|
||||||
RefPtr<StyleValue const> Parser::parse_touch_action_value(TokenStream<ComponentValue>& tokens)
|
RefPtr<StyleValue const> Parser::parse_touch_action_value(TokenStream<ComponentValue>& tokens)
|
||||||
{
|
{
|
||||||
|
|
|
@ -3383,6 +3383,15 @@
|
||||||
],
|
],
|
||||||
"percentages-resolve-to": "length"
|
"percentages-resolve-to": "length"
|
||||||
},
|
},
|
||||||
|
"text-underline-position": {
|
||||||
|
"animation-type": "discrete",
|
||||||
|
"inherited": true,
|
||||||
|
"initial": "auto",
|
||||||
|
"valid-types": [
|
||||||
|
"text-underline-position-horizontal",
|
||||||
|
"text-underline-position-vertical"
|
||||||
|
]
|
||||||
|
},
|
||||||
"text-wrap": {
|
"text-wrap": {
|
||||||
"inherited": true,
|
"inherited": true,
|
||||||
"initial": "wrap",
|
"initial": "wrap",
|
||||||
|
|
|
@ -66,6 +66,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/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>
|
||||||
#include <LibWeb/CSS/StyleValues/TransitionStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/TransitionStyleValue.h>
|
||||||
|
|
|
@ -30,64 +30,65 @@
|
||||||
|
|
||||||
namespace Web::CSS {
|
namespace Web::CSS {
|
||||||
|
|
||||||
#define ENUMERATE_CSS_STYLE_VALUE_TYPES \
|
#define ENUMERATE_CSS_STYLE_VALUE_TYPES \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Anchor, anchor, AnchorStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Anchor, anchor, AnchorStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(AnchorSize, anchor_size, AnchorSizeStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(AnchorSize, anchor_size, AnchorSizeStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Angle, angle, AngleStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Angle, angle, AngleStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(BackgroundSize, background_size, BackgroundSizeStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(BackgroundSize, background_size, BackgroundSizeStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(BasicShape, basic_shape, BasicShapeStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(BasicShape, basic_shape, BasicShapeStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(BorderImageSlice, border_image_slice, BorderImageSliceStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(BorderImageSlice, border_image_slice, BorderImageSliceStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(BorderRadius, border_radius, BorderRadiusStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(BorderRadius, border_radius, BorderRadiusStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Calculated, calculated, CalculatedStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Calculated, calculated, CalculatedStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(ColorScheme, color_scheme, ColorSchemeStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(ColorScheme, color_scheme, ColorSchemeStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Color, color, ColorStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Color, color, ColorStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(ConicGradient, conic_gradient, ConicGradientStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(ConicGradient, conic_gradient, ConicGradientStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Content, content, ContentStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Content, content, ContentStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Counter, counter, CounterStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Counter, counter, CounterStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(CounterDefinitions, counter_definitions, CounterDefinitionsStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(CounterDefinitions, counter_definitions, CounterDefinitionsStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Cursor, cursor, CursorStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Cursor, cursor, CursorStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(CustomIdent, custom_ident, CustomIdentStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(CustomIdent, custom_ident, CustomIdentStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Display, display, DisplayStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Display, display, DisplayStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Easing, easing, EasingStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Easing, easing, EasingStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Edge, edge, EdgeStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Edge, edge, EdgeStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(FilterValueList, filter_value_list, FilterValueListStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(FilterValueList, filter_value_list, FilterValueListStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(FitContent, fit_content, FitContentStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(FitContent, fit_content, FitContentStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Flex, flex, FlexStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Flex, flex, FlexStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(FontSource, font_source, FontSourceStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(FontSource, font_source, FontSourceStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(FontStyle, font_style, FontStyleStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(FontStyle, font_style, FontStyleStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Frequency, frequency, FrequencyStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Frequency, frequency, FrequencyStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(GridAutoFlow, grid_auto_flow, GridAutoFlowStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(GridAutoFlow, grid_auto_flow, GridAutoFlowStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(GridTemplateArea, grid_template_area, GridTemplateAreaStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(GridTemplateArea, grid_template_area, GridTemplateAreaStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(GridTrackPlacement, grid_track_placement, GridTrackPlacementStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(GridTrackPlacement, grid_track_placement, GridTrackPlacementStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(GridTrackSizeList, grid_track_size_list, GridTrackSizeListStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(GridTrackSizeList, grid_track_size_list, GridTrackSizeListStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(GuaranteedInvalid, guaranteed_invalid, GuaranteedInvalidStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(GuaranteedInvalid, guaranteed_invalid, GuaranteedInvalidStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Image, image, ImageStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Image, image, ImageStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Integer, integer, IntegerStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Integer, integer, IntegerStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Keyword, keyword, KeywordStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Keyword, keyword, KeywordStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Length, length, LengthStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Length, length, LengthStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(LinearGradient, linear_gradient, LinearGradientStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(LinearGradient, linear_gradient, LinearGradientStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(MathDepth, math_depth, MathDepthStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(MathDepth, math_depth, MathDepthStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Number, number, NumberStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Number, number, NumberStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(OpenTypeTagged, open_type_tagged, OpenTypeTaggedStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(OpenTypeTagged, open_type_tagged, OpenTypeTaggedStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(PendingSubstitution, pending_substitution, PendingSubstitutionStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(PendingSubstitution, pending_substitution, PendingSubstitutionStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Percentage, percentage, PercentageStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Percentage, percentage, PercentageStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Position, position, PositionStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Position, position, PositionStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(RadialGradient, radial_gradient, RadialGradientStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(RadialGradient, radial_gradient, RadialGradientStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Ratio, ratio, RatioStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Ratio, ratio, RatioStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Rect, rect, RectStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Rect, rect, RectStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(RepeatStyle, repeat_style, RepeatStyleStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(RepeatStyle, repeat_style, RepeatStyleStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Resolution, resolution, ResolutionStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Resolution, resolution, ResolutionStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(ScrollbarColor, scrollbar_color, ScrollbarColorStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(ScrollbarColor, scrollbar_color, ScrollbarColorStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(ScrollbarGutter, scrollbar_gutter, ScrollbarGutterStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(ScrollbarGutter, scrollbar_gutter, ScrollbarGutterStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Shadow, shadow, ShadowStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Shadow, shadow, ShadowStyleValue) \
|
||||||
__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(Time, time, TimeStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(TextUnderlinePosition, text_underline_position, TextUnderlinePositionStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Transformation, transformation, TransformationStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Time, time, TimeStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Transition, transition, TransitionStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Transformation, transformation, TransformationStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(UnicodeRange, unicode_range, UnicodeRangeStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Transition, transition, TransitionStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Unresolved, unresolved, UnresolvedStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(UnicodeRange, unicode_range, UnicodeRangeStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(URL, url, URLStyleValue) \
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(Unresolved, unresolved, UnresolvedStyleValue) \
|
||||||
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(URL, url, URLStyleValue) \
|
||||||
__ENUMERATE_CSS_STYLE_VALUE_TYPE(ValueList, value_list, StyleValueList)
|
__ENUMERATE_CSS_STYLE_VALUE_TYPE(ValueList, value_list, StyleValueList)
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Callum Law <callumlaw1709@outlook.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <LibWeb/CSS/StyleValues/TextUnderlinePositionStyleValue.h>
|
||||||
|
|
||||||
|
namespace Web::CSS {
|
||||||
|
|
||||||
|
String TextUnderlinePositionStyleValue::to_string(SerializationMode) const
|
||||||
|
{
|
||||||
|
if (m_horizontal == TextUnderlinePositionHorizontal::Auto && m_vertical == TextUnderlinePositionVertical::Auto)
|
||||||
|
return "auto"_string;
|
||||||
|
|
||||||
|
if (m_vertical == TextUnderlinePositionVertical::Auto)
|
||||||
|
return MUST(String::from_utf8(CSS::to_string(m_horizontal)));
|
||||||
|
|
||||||
|
if (m_horizontal == TextUnderlinePositionHorizontal::Auto)
|
||||||
|
return MUST(String::from_utf8(CSS::to_string(m_vertical)));
|
||||||
|
|
||||||
|
return MUST(String::formatted("{} {}", CSS::to_string(m_horizontal), CSS::to_string(m_vertical)));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Callum Law <callumlaw1709@outlook.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <LibWeb/CSS/Enums.h>
|
||||||
|
#include <LibWeb/CSS/StyleValues/StyleValue.h>
|
||||||
|
|
||||||
|
namespace Web::CSS {
|
||||||
|
|
||||||
|
class TextUnderlinePositionStyleValue : public StyleValueWithDefaultOperators<TextUnderlinePositionStyleValue> {
|
||||||
|
public:
|
||||||
|
static ValueComparingNonnullRefPtr<TextUnderlinePositionStyleValue const> create(TextUnderlinePositionHorizontal horizontal, TextUnderlinePositionVertical vertical)
|
||||||
|
{
|
||||||
|
return adopt_ref(*new (nothrow) TextUnderlinePositionStyleValue(horizontal, vertical));
|
||||||
|
}
|
||||||
|
virtual ~TextUnderlinePositionStyleValue() override = default;
|
||||||
|
|
||||||
|
TextUnderlinePositionHorizontal horizontal() const { return m_horizontal; }
|
||||||
|
TextUnderlinePositionVertical vertical() const { return m_vertical; }
|
||||||
|
|
||||||
|
virtual String to_string(SerializationMode serialization_mode) const override;
|
||||||
|
|
||||||
|
bool properties_equal(TextUnderlinePositionStyleValue const& other) const { return m_horizontal == other.m_horizontal && m_vertical == other.m_vertical; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
explicit TextUnderlinePositionStyleValue(TextUnderlinePositionHorizontal horizontal, TextUnderlinePositionVertical vertical)
|
||||||
|
: StyleValueWithDefaultOperators(Type::TextUnderlinePosition)
|
||||||
|
, m_horizontal(horizontal)
|
||||||
|
, m_vertical(vertical)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
TextUnderlinePositionHorizontal m_horizontal;
|
||||||
|
TextUnderlinePositionVertical m_vertical;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -364,6 +364,7 @@ class StyleValue;
|
||||||
class StyleValueList;
|
class StyleValueList;
|
||||||
class Supports;
|
class Supports;
|
||||||
class SVGPaint;
|
class SVGPaint;
|
||||||
|
class TextUnderlinePositionStyleValue;
|
||||||
class Time;
|
class Time;
|
||||||
class TimeOrCalculated;
|
class TimeOrCalculated;
|
||||||
class TimePercentage;
|
class TimePercentage;
|
||||||
|
|
|
@ -63,6 +63,7 @@ All properties associated with getComputedStyle(document.body):
|
||||||
"text-shadow",
|
"text-shadow",
|
||||||
"text-transform",
|
"text-transform",
|
||||||
"text-underline-offset",
|
"text-underline-offset",
|
||||||
|
"text-underline-position",
|
||||||
"text-wrap-mode",
|
"text-wrap-mode",
|
||||||
"text-wrap-style",
|
"text-wrap-style",
|
||||||
"visibility",
|
"visibility",
|
||||||
|
|
|
@ -691,6 +691,8 @@ All supported properties and their default values exposed from CSSStylePropertie
|
||||||
'text-transform': 'none'
|
'text-transform': 'none'
|
||||||
'textUnderlineOffset': 'auto'
|
'textUnderlineOffset': 'auto'
|
||||||
'text-underline-offset': 'auto'
|
'text-underline-offset': 'auto'
|
||||||
|
'textUnderlinePosition': 'auto'
|
||||||
|
'text-underline-position': 'auto'
|
||||||
'textWrap': 'wrap'
|
'textWrap': 'wrap'
|
||||||
'text-wrap': 'wrap'
|
'text-wrap': 'wrap'
|
||||||
'textWrapMode': 'wrap'
|
'textWrapMode': 'wrap'
|
||||||
|
|
|
@ -61,6 +61,7 @@ text-rendering: auto
|
||||||
text-shadow: none
|
text-shadow: none
|
||||||
text-transform: none
|
text-transform: none
|
||||||
text-underline-offset: auto
|
text-underline-offset: auto
|
||||||
|
text-underline-position: auto
|
||||||
text-wrap-mode: wrap
|
text-wrap-mode: wrap
|
||||||
text-wrap-style: auto
|
text-wrap-style: auto
|
||||||
visibility: visible
|
visibility: visible
|
||||||
|
@ -93,7 +94,7 @@ background-position-x: 0%
|
||||||
background-position-y: 0%
|
background-position-y: 0%
|
||||||
background-repeat: repeat
|
background-repeat: repeat
|
||||||
background-size: auto
|
background-size: auto
|
||||||
block-size: 1425px
|
block-size: 1440px
|
||||||
border-block-end-color: rgb(0, 0, 0)
|
border-block-end-color: rgb(0, 0, 0)
|
||||||
border-block-end-style: none
|
border-block-end-style: none
|
||||||
border-block-end-width: 0px
|
border-block-end-width: 0px
|
||||||
|
@ -170,7 +171,7 @@ grid-row-start: auto
|
||||||
grid-template-areas: none
|
grid-template-areas: none
|
||||||
grid-template-columns: none
|
grid-template-columns: none
|
||||||
grid-template-rows: none
|
grid-template-rows: none
|
||||||
height: 2580px
|
height: 2595px
|
||||||
inline-size: 784px
|
inline-size: 784px
|
||||||
inset-block-end: auto
|
inset-block-end: auto
|
||||||
inset-block-start: auto
|
inset-block-start: auto
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
Harness status: OK
|
Harness status: OK
|
||||||
|
|
||||||
Found 259 tests
|
Found 260 tests
|
||||||
|
|
||||||
252 Pass
|
253 Pass
|
||||||
7 Fail
|
7 Fail
|
||||||
Pass accent-color
|
Pass accent-color
|
||||||
Pass border-collapse
|
Pass border-collapse
|
||||||
|
@ -65,6 +65,7 @@ Pass text-rendering
|
||||||
Pass text-shadow
|
Pass text-shadow
|
||||||
Pass text-transform
|
Pass text-transform
|
||||||
Pass text-underline-offset
|
Pass text-underline-offset
|
||||||
|
Pass text-underline-position
|
||||||
Pass text-wrap-mode
|
Pass text-wrap-mode
|
||||||
Pass text-wrap-style
|
Pass text-wrap-style
|
||||||
Pass visibility
|
Pass visibility
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
Harness status: OK
|
||||||
|
|
||||||
|
Found 7 tests
|
||||||
|
|
||||||
|
7 Pass
|
||||||
|
Pass Property text-underline-position value 'auto'
|
||||||
|
Pass Property text-underline-position value 'under'
|
||||||
|
Pass Property text-underline-position value 'from-font'
|
||||||
|
Pass Property text-underline-position value 'left'
|
||||||
|
Pass Property text-underline-position value 'right'
|
||||||
|
Pass Property text-underline-position value 'under left'
|
||||||
|
Pass Property text-underline-position value 'from-font left'
|
|
@ -0,0 +1,11 @@
|
||||||
|
Harness status: OK
|
||||||
|
|
||||||
|
Found 6 tests
|
||||||
|
|
||||||
|
6 Pass
|
||||||
|
Pass e.style['text-underline-position'] = "auto under" should not set the property value
|
||||||
|
Pass e.style['text-underline-position'] = "auto from-font" should not set the property value
|
||||||
|
Pass e.style['text-underline-position'] = "left auto" should not set the property value
|
||||||
|
Pass e.style['text-underline-position'] = "left right" should not set the property value
|
||||||
|
Pass e.style['text-underline-position'] = "right under left" should not set the property value
|
||||||
|
Pass e.style['text-underline-position'] = "under from-font" should not set the property value
|
|
@ -0,0 +1,14 @@
|
||||||
|
Harness status: OK
|
||||||
|
|
||||||
|
Found 9 tests
|
||||||
|
|
||||||
|
9 Pass
|
||||||
|
Pass e.style['text-underline-position'] = "auto" should set the property value
|
||||||
|
Pass e.style['text-underline-position'] = "under" should set the property value
|
||||||
|
Pass e.style['text-underline-position'] = "from-font" should set the property value
|
||||||
|
Pass e.style['text-underline-position'] = "left" should set the property value
|
||||||
|
Pass e.style['text-underline-position'] = "right" should set the property value
|
||||||
|
Pass e.style['text-underline-position'] = "under left" should set the property value
|
||||||
|
Pass e.style['text-underline-position'] = "from-font left" should set the property value
|
||||||
|
Pass e.style['text-underline-position'] = "right under" should set the property value
|
||||||
|
Pass e.style['text-underline-position'] = "right from-font" should set the property value
|
|
@ -0,0 +1,25 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>CSS Text Decoration Test: getComputedStyle().textUnderlinePosition</title>
|
||||||
|
<link rel="help" href="https://drafts.csswg.org/css-text-decor-3/#text-decoration-style-property">
|
||||||
|
<meta name="assert" content="text-underline-position computed value is as specified.">
|
||||||
|
<script src="../../../resources/testharness.js"></script>
|
||||||
|
<script src="../../../resources/testharnessreport.js"></script>
|
||||||
|
<script src="../../../css/support/computed-testcommon.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="target"></div>
|
||||||
|
<script>
|
||||||
|
test_computed_value("text-underline-position", "auto");
|
||||||
|
|
||||||
|
test_computed_value("text-underline-position", "under");
|
||||||
|
test_computed_value("text-underline-position", "from-font");
|
||||||
|
test_computed_value("text-underline-position", "left");
|
||||||
|
test_computed_value("text-underline-position", "right");
|
||||||
|
test_computed_value("text-underline-position", "under left");
|
||||||
|
test_computed_value("text-underline-position", "from-font left");
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,16 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>CSS Text Decoration Test: Parsing text-underline-position with invalid values</title>
|
||||||
|
<link rel="help" href="https://drafts.csswg.org/css-text-decor-3/#text-decoration-style-property">
|
||||||
|
<meta name="assert" content="text-underline-position supports only the grammar 'auto | [ under || [ left | right ] ]'.">
|
||||||
|
<script src="../../../resources/testharness.js"></script>
|
||||||
|
<script src="../../../resources/testharnessreport.js"></script>
|
||||||
|
<script src="../../../css/support/parsing-testcommon.js"></script>
|
||||||
|
<script>
|
||||||
|
test_invalid_value("text-underline-position", "auto under");
|
||||||
|
test_invalid_value("text-underline-position", "auto from-font");
|
||||||
|
test_invalid_value("text-underline-position", "left auto");
|
||||||
|
test_invalid_value("text-underline-position", "left right");
|
||||||
|
test_invalid_value("text-underline-position", "right under left");
|
||||||
|
test_invalid_value("text-underline-position", "under from-font");
|
||||||
|
</script>
|
|
@ -0,0 +1,20 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>CSS Text Decoration Test: Parsing text-underline-position with valid values</title>
|
||||||
|
<link rel="help" href="https://drafts.csswg.org/css-text-decor-3/#text-decoration-style-property">
|
||||||
|
<meta name="assert" content="text-underline-position supports the full grammar 'auto | [ under || [ left | right ] ]'.">
|
||||||
|
<script src="../../../resources/testharness.js"></script>
|
||||||
|
<script src="../../../resources/testharnessreport.js"></script>
|
||||||
|
<script src="../../../css/support/parsing-testcommon.js"></script>
|
||||||
|
<script>
|
||||||
|
test_valid_value("text-underline-position", "auto");
|
||||||
|
|
||||||
|
test_valid_value("text-underline-position", "under");
|
||||||
|
test_valid_value("text-underline-position", "from-font");
|
||||||
|
test_valid_value("text-underline-position", "left");
|
||||||
|
test_valid_value("text-underline-position", "right");
|
||||||
|
test_valid_value("text-underline-position", "under left");
|
||||||
|
test_valid_value("text-underline-position", "from-font left");
|
||||||
|
test_valid_value("text-underline-position", "right under", "under right");
|
||||||
|
test_valid_value("text-underline-position", "right from-font", "from-font right");
|
||||||
|
</script>
|
Loading…
Add table
Add a link
Reference in a new issue