mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-01-22 09:12:13 -05:00
LibWeb: Properly serialize position/edge style values
This commit is contained in:
parent
583ca6af89
commit
84150f972f
Notes:
github-actions[bot]
2024-12-13 11:36:34 +00:00
Author: https://github.com/Gingeh Commit: https://github.com/LadybirdBrowser/ladybird/commit/84150f972f9 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/2651 Reviewed-by: https://github.com/AtkinsSJ ✅ Reviewed-by: https://github.com/awesomekling
21 changed files with 461 additions and 288 deletions
|
@ -3913,12 +3913,6 @@ RefPtr<PositionStyleValue> Parser::parse_position_value(TokenStream<ComponentVal
|
|||
}
|
||||
};
|
||||
|
||||
auto make_edge_style_value = [](PositionEdge position_edge, bool is_horizontal) -> NonnullRefPtr<EdgeStyleValue> {
|
||||
if (position_edge == PositionEdge::Center)
|
||||
return EdgeStyleValue::create(is_horizontal ? PositionEdge::Left : PositionEdge::Top, Percentage { 50 });
|
||||
return EdgeStyleValue::create(position_edge, Length::make_px(0));
|
||||
};
|
||||
|
||||
// <position> = [
|
||||
// [ left | center | right | top | bottom | <length-percentage> ]
|
||||
// |
|
||||
|
@ -3945,21 +3939,21 @@ RefPtr<PositionStyleValue> Parser::parse_position_value(TokenStream<ComponentVal
|
|||
|
||||
// [ left | right ]
|
||||
if (is_horizontal(edge, false))
|
||||
return PositionStyleValue::create(make_edge_style_value(edge, true), make_edge_style_value(PositionEdge::Center, false));
|
||||
return PositionStyleValue::create(EdgeStyleValue::create(edge, {}), EdgeStyleValue::create(PositionEdge::Center, {}));
|
||||
|
||||
// [ top | bottom ]
|
||||
if (is_vertical(edge, false))
|
||||
return PositionStyleValue::create(make_edge_style_value(PositionEdge::Center, true), make_edge_style_value(edge, false));
|
||||
return PositionStyleValue::create(EdgeStyleValue::create(PositionEdge::Center, {}), EdgeStyleValue::create(edge, {}));
|
||||
|
||||
// [ center ]
|
||||
VERIFY(edge == PositionEdge::Center);
|
||||
return PositionStyleValue::create(make_edge_style_value(PositionEdge::Center, true), make_edge_style_value(PositionEdge::Center, false));
|
||||
return PositionStyleValue::create(EdgeStyleValue::create(PositionEdge::Center, {}), EdgeStyleValue::create(PositionEdge::Center, {}));
|
||||
}
|
||||
|
||||
// [ <length-percentage> ]
|
||||
if (auto maybe_percentage = parse_length_percentage(token); maybe_percentage.has_value()) {
|
||||
transaction.commit();
|
||||
return PositionStyleValue::create(EdgeStyleValue::create(PositionEdge::Left, *maybe_percentage), make_edge_style_value(PositionEdge::Center, false));
|
||||
return PositionStyleValue::create(EdgeStyleValue::create({}, *maybe_percentage), EdgeStyleValue::create(PositionEdge::Center, {}));
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
@ -3994,7 +3988,7 @@ RefPtr<PositionStyleValue> Parser::parse_position_value(TokenStream<ComponentVal
|
|||
// [ left | center | right ] [ top | bottom | center ]
|
||||
if (is_horizontal(first_edge, true) && is_vertical(second_edge, true)) {
|
||||
transaction.commit();
|
||||
return PositionStyleValue::create(make_edge_style_value(first_edge, true), make_edge_style_value(second_edge, false));
|
||||
return PositionStyleValue::create(EdgeStyleValue::create(first_edge, {}), EdgeStyleValue::create(second_edge, {}));
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
@ -4014,14 +4008,14 @@ RefPtr<PositionStyleValue> Parser::parse_position_value(TokenStream<ComponentVal
|
|||
bool valid = as_horizontal ? is_horizontal(position, true) : is_vertical(position, true);
|
||||
if (!valid)
|
||||
return nullptr;
|
||||
return make_edge_style_value(position, as_horizontal);
|
||||
return EdgeStyleValue::create(position, {});
|
||||
}
|
||||
|
||||
auto maybe_length = parse_length_percentage(token);
|
||||
if (!maybe_length.has_value())
|
||||
return nullptr;
|
||||
|
||||
return EdgeStyleValue::create(as_horizontal ? PositionEdge::Left : PositionEdge::Top, maybe_length.release_value());
|
||||
return EdgeStyleValue::create({}, maybe_length);
|
||||
};
|
||||
|
||||
// [ left | center | right | <length-percentage> ]
|
||||
|
@ -4157,15 +4151,15 @@ RefPtr<PositionStyleValue> Parser::parse_position_value(TokenStream<ComponentVal
|
|||
if (!is_vertical(group2.position, true))
|
||||
return nullptr;
|
||||
|
||||
auto to_style_value = [&](PositionAndMaybeLength const& group, bool is_horizontal) -> NonnullRefPtr<EdgeStyleValue> {
|
||||
auto to_style_value = [&](PositionAndMaybeLength const& group) -> NonnullRefPtr<EdgeStyleValue> {
|
||||
if (group.position == PositionEdge::Center)
|
||||
return EdgeStyleValue::create(is_horizontal ? PositionEdge::Left : PositionEdge::Top, Percentage { 50 });
|
||||
return EdgeStyleValue::create(PositionEdge::Center, {});
|
||||
|
||||
return EdgeStyleValue::create(group.position, group.length.value_or(Length::make_px(0)));
|
||||
return EdgeStyleValue::create(group.position, group.length);
|
||||
};
|
||||
|
||||
transaction.commit();
|
||||
return PositionStyleValue::create(to_style_value(group1, true), to_style_value(group2, false));
|
||||
return PositionStyleValue::create(to_style_value(group1), to_style_value(group2));
|
||||
};
|
||||
|
||||
// Note: The alternatives must be attempted in this order since shorter alternatives can match a prefix of longer ones.
|
||||
|
@ -4527,16 +4521,7 @@ static Optional<LengthPercentage> style_value_to_length_percentage(auto value)
|
|||
|
||||
RefPtr<CSSStyleValue> Parser::parse_single_background_position_x_or_y_value(TokenStream<ComponentValue>& tokens, PropertyID property)
|
||||
{
|
||||
PositionEdge relative_edge {};
|
||||
if (property == PropertyID::BackgroundPositionX) {
|
||||
// [ center | [ [ left | right | x-start | x-end ]? <length-percentage>? ]! ]#
|
||||
relative_edge = PositionEdge::Left;
|
||||
} else if (property == PropertyID::BackgroundPositionY) {
|
||||
// [ center | [ [ top | bottom | y-start | y-end ]? <length-percentage>? ]! ]#
|
||||
relative_edge = PositionEdge::Top;
|
||||
} else {
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
Optional<PositionEdge> relative_edge {};
|
||||
|
||||
auto transaction = tokens.begin_transaction();
|
||||
if (!tokens.has_next_token())
|
||||
|
@ -4550,10 +4535,10 @@ RefPtr<CSSStyleValue> Parser::parse_single_background_position_x_or_y_value(Toke
|
|||
auto keyword = value->to_keyword();
|
||||
if (keyword == Keyword::Center) {
|
||||
transaction.commit();
|
||||
return EdgeStyleValue::create(relative_edge, Percentage { 50 });
|
||||
return EdgeStyleValue::create(PositionEdge::Center, {});
|
||||
}
|
||||
if (auto edge = keyword_to_position_edge(keyword); edge.has_value()) {
|
||||
relative_edge = *edge;
|
||||
relative_edge = edge;
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -4561,7 +4546,7 @@ RefPtr<CSSStyleValue> Parser::parse_single_background_position_x_or_y_value(Toke
|
|||
value = parse_css_value_for_property(property, tokens);
|
||||
if (!value) {
|
||||
transaction.commit();
|
||||
return EdgeStyleValue::create(relative_edge, Length::make_px(0));
|
||||
return EdgeStyleValue::create(relative_edge, {});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4572,9 +4557,21 @@ RefPtr<CSSStyleValue> Parser::parse_single_background_position_x_or_y_value(Toke
|
|||
return EdgeStyleValue::create(relative_edge, *offset);
|
||||
}
|
||||
|
||||
if (!relative_edge.has_value()) {
|
||||
if (property == PropertyID::BackgroundPositionX) {
|
||||
// [ center | [ [ left | right | x-start | x-end ]? <length-percentage>? ]! ]#
|
||||
relative_edge = PositionEdge::Left;
|
||||
} else if (property == PropertyID::BackgroundPositionY) {
|
||||
// [ center | [ [ top | bottom | y-start | y-end ]? <length-percentage>? ]! ]#
|
||||
relative_edge = PositionEdge::Top;
|
||||
} else {
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
||||
// If no offset is provided create this element but with an offset of default value of zero
|
||||
transaction.commit();
|
||||
return EdgeStyleValue::create(relative_edge, Length::make_px(0));
|
||||
return EdgeStyleValue::create(relative_edge, {});
|
||||
}
|
||||
|
||||
RefPtr<CSSStyleValue> Parser::parse_single_background_repeat_value(TokenStream<ComponentValue>& tokens)
|
||||
|
|
|
@ -82,20 +82,6 @@ String ResolvedCSSStyleDeclaration::item(size_t index) const
|
|||
return string_from_property_id(property_id).to_string();
|
||||
}
|
||||
|
||||
static NonnullRefPtr<CSSStyleValue const> style_value_for_background_property(Layout::NodeWithStyle const& layout_node, Function<NonnullRefPtr<CSSStyleValue const>(BackgroundLayerData const&)> callback, Function<NonnullRefPtr<CSSStyleValue const>()> default_value)
|
||||
{
|
||||
auto const& background_layers = layout_node.background_layers();
|
||||
if (background_layers.is_empty())
|
||||
return default_value();
|
||||
if (background_layers.size() == 1)
|
||||
return callback(background_layers.first());
|
||||
StyleValueVector values;
|
||||
values.ensure_capacity(background_layers.size());
|
||||
for (auto const& layer : background_layers)
|
||||
values.unchecked_append(callback(layer));
|
||||
return StyleValueList::create(move(values), StyleValueList::Separator::Comma);
|
||||
}
|
||||
|
||||
static NonnullRefPtr<CSSStyleValue const> style_value_for_length_percentage(LengthPercentage const& length_percentage)
|
||||
{
|
||||
if (length_percentage.is_auto())
|
||||
|
@ -453,19 +439,6 @@ RefPtr<CSSStyleValue const> ResolvedCSSStyleDeclaration::style_value_for_propert
|
|||
// NOTE: This is handled inside the `default` case.
|
||||
|
||||
// NOTE: Everything below is a shorthand that requires some manual construction.
|
||||
case PropertyID::BackgroundPosition:
|
||||
return style_value_for_background_property(
|
||||
layout_node,
|
||||
[](auto& layer) -> NonnullRefPtr<CSSStyleValue> {
|
||||
return PositionStyleValue::create(
|
||||
EdgeStyleValue::create(layer.position_edge_x, layer.position_offset_x),
|
||||
EdgeStyleValue::create(layer.position_edge_y, layer.position_offset_y));
|
||||
},
|
||||
[]() -> NonnullRefPtr<CSSStyleValue> {
|
||||
return PositionStyleValue::create(
|
||||
EdgeStyleValue::create(PositionEdge::Left, Percentage(0)),
|
||||
EdgeStyleValue::create(PositionEdge::Top, Percentage(0)));
|
||||
});
|
||||
case PropertyID::Border: {
|
||||
auto width = style_value_for_property(layout_node, PropertyID::BorderWidth);
|
||||
auto style = style_value_for_property(layout_node, PropertyID::BorderStyle);
|
||||
|
|
|
@ -1325,12 +1325,12 @@ CSS::ObjectPosition StyleProperties::object_position() const
|
|||
auto const& edge_y = position.edge_y();
|
||||
if (edge_x->is_edge()) {
|
||||
auto const& edge = edge_x->as_edge();
|
||||
object_position.edge_x = edge.edge();
|
||||
object_position.edge_x = edge.edge().value_or(PositionEdge::Left);
|
||||
object_position.offset_x = edge.offset();
|
||||
}
|
||||
if (edge_y->is_edge()) {
|
||||
auto const& edge = edge_y->as_edge();
|
||||
object_position.edge_y = edge.edge();
|
||||
object_position.edge_y = edge.edge().value_or(PositionEdge::Top);
|
||||
object_position.offset_y = edge.offset();
|
||||
}
|
||||
return object_position;
|
||||
|
|
|
@ -34,7 +34,7 @@ Gfx::Path Inset::to_path(CSSPixelRect reference_box, Layout::Node const& node) c
|
|||
return path_from_resolved_rect(top, right, bottom, left);
|
||||
}
|
||||
|
||||
String Inset::to_string() const
|
||||
String Inset::to_string(CSSStyleValue::SerializationMode) const
|
||||
{
|
||||
return MUST(String::formatted("inset({} {} {} {})", inset_box.top(), inset_box.right(), inset_box.bottom(), inset_box.left()));
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ Gfx::Path Xywh::to_path(CSSPixelRect reference_box, Layout::Node const& node) co
|
|||
return path_from_resolved_rect(top, right, bottom, left);
|
||||
}
|
||||
|
||||
String Xywh::to_string() const
|
||||
String Xywh::to_string(CSSStyleValue::SerializationMode) const
|
||||
{
|
||||
return MUST(String::formatted("xywh({} {} {} {})", x, y, width, height));
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ Gfx::Path Rect::to_path(CSSPixelRect reference_box, Layout::Node const& node) co
|
|||
return path_from_resolved_rect(top, max(right, left), max(bottom, top), left);
|
||||
}
|
||||
|
||||
String Rect::to_string() const
|
||||
String Rect::to_string(CSSStyleValue::SerializationMode) const
|
||||
{
|
||||
return MUST(String::formatted("rect({} {} {} {})", box.top(), box.right(), box.bottom(), box.left()));
|
||||
}
|
||||
|
@ -123,9 +123,9 @@ Gfx::Path Circle::to_path(CSSPixelRect reference_box, Layout::Node const& node)
|
|||
return path;
|
||||
}
|
||||
|
||||
String Circle::to_string() const
|
||||
String Circle::to_string(CSSStyleValue::SerializationMode mode) const
|
||||
{
|
||||
return MUST(String::formatted("circle({} at {})", radius_to_string(radius), position->to_string(CSSStyleValue::SerializationMode::Normal)));
|
||||
return MUST(String::formatted("circle({} at {})", radius_to_string(radius), position->to_string(mode)));
|
||||
}
|
||||
|
||||
Gfx::Path Ellipse::to_path(CSSPixelRect reference_box, Layout::Node const& node) const
|
||||
|
@ -168,9 +168,9 @@ Gfx::Path Ellipse::to_path(CSSPixelRect reference_box, Layout::Node const& node)
|
|||
return path;
|
||||
}
|
||||
|
||||
String Ellipse::to_string() const
|
||||
String Ellipse::to_string(CSSStyleValue::SerializationMode mode) const
|
||||
{
|
||||
return MUST(String::formatted("ellipse({} {} at {})", radius_to_string(radius_x), radius_to_string(radius_y), position->to_string(CSSStyleValue::SerializationMode::Normal)));
|
||||
return MUST(String::formatted("ellipse({} {} at {})", radius_to_string(radius_x), radius_to_string(radius_y), position->to_string(mode)));
|
||||
}
|
||||
|
||||
Gfx::Path Polygon::to_path(CSSPixelRect reference_box, Layout::Node const& node) const
|
||||
|
@ -193,7 +193,7 @@ Gfx::Path Polygon::to_path(CSSPixelRect reference_box, Layout::Node const& node)
|
|||
return path;
|
||||
}
|
||||
|
||||
String Polygon::to_string() const
|
||||
String Polygon::to_string(CSSStyleValue::SerializationMode) const
|
||||
{
|
||||
StringBuilder builder;
|
||||
builder.append("polygon("sv);
|
||||
|
@ -220,10 +220,10 @@ Gfx::Path BasicShapeStyleValue::to_path(CSSPixelRect reference_box, Layout::Node
|
|||
});
|
||||
}
|
||||
|
||||
String BasicShapeStyleValue::to_string(SerializationMode) const
|
||||
String BasicShapeStyleValue::to_string(SerializationMode mode) const
|
||||
{
|
||||
return m_basic_shape.visit([](auto const& shape) {
|
||||
return shape.to_string();
|
||||
return m_basic_shape.visit([mode](auto const& shape) {
|
||||
return shape.to_string(mode);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ namespace Web::CSS {
|
|||
|
||||
struct Inset {
|
||||
Gfx::Path to_path(CSSPixelRect reference_box, Layout::Node const&) const;
|
||||
String to_string() const;
|
||||
String to_string(CSSStyleValue::SerializationMode) const;
|
||||
|
||||
bool operator==(Inset const&) const = default;
|
||||
|
||||
|
@ -26,7 +26,7 @@ struct Inset {
|
|||
|
||||
struct Xywh {
|
||||
Gfx::Path to_path(CSSPixelRect reference_box, Layout::Node const&) const;
|
||||
String to_string() const;
|
||||
String to_string(CSSStyleValue::SerializationMode) const;
|
||||
|
||||
bool operator==(Xywh const&) const = default;
|
||||
|
||||
|
@ -38,7 +38,7 @@ struct Xywh {
|
|||
|
||||
struct Rect {
|
||||
Gfx::Path to_path(CSSPixelRect reference_box, Layout::Node const&) const;
|
||||
String to_string() const;
|
||||
String to_string(CSSStyleValue::SerializationMode) const;
|
||||
|
||||
bool operator==(Rect const&) const = default;
|
||||
|
||||
|
@ -54,7 +54,7 @@ using ShapeRadius = Variant<LengthPercentage, FitSide>;
|
|||
|
||||
struct Circle {
|
||||
Gfx::Path to_path(CSSPixelRect reference_box, Layout::Node const&) const;
|
||||
String to_string() const;
|
||||
String to_string(CSSStyleValue::SerializationMode) const;
|
||||
|
||||
bool operator==(Circle const&) const = default;
|
||||
|
||||
|
@ -64,7 +64,7 @@ struct Circle {
|
|||
|
||||
struct Ellipse {
|
||||
Gfx::Path to_path(CSSPixelRect reference_box, Layout::Node const&) const;
|
||||
String to_string() const;
|
||||
String to_string(CSSStyleValue::SerializationMode) const;
|
||||
|
||||
bool operator==(Ellipse const&) const = default;
|
||||
|
||||
|
@ -81,7 +81,7 @@ struct Polygon {
|
|||
};
|
||||
|
||||
Gfx::Path to_path(CSSPixelRect reference_box, Layout::Node const&) const;
|
||||
String to_string() const;
|
||||
String to_string(CSSStyleValue::SerializationMode) const;
|
||||
|
||||
bool operator==(Polygon const&) const = default;
|
||||
|
||||
|
|
|
@ -8,9 +8,40 @@
|
|||
|
||||
namespace Web::CSS {
|
||||
|
||||
String EdgeStyleValue::to_string(SerializationMode) const
|
||||
String EdgeStyleValue::to_string(SerializationMode mode) const
|
||||
{
|
||||
return MUST(String::formatted("{} {}", CSS::to_string(m_properties.edge), m_properties.offset.to_string()));
|
||||
if (mode == CSSStyleValue::SerializationMode::ResolvedValue) {
|
||||
if (edge() == PositionEdge::Right || edge() == PositionEdge::Bottom) {
|
||||
if (offset().is_percentage()) {
|
||||
auto flipped_percentage = 100 - offset().percentage().value();
|
||||
return Percentage(flipped_percentage).to_string();
|
||||
}
|
||||
Vector<NonnullOwnPtr<CalculationNode>> sum_parts;
|
||||
sum_parts.append(NumericCalculationNode::create(Percentage(100)));
|
||||
if (offset().is_length()) {
|
||||
sum_parts.append(NegateCalculationNode::create(NumericCalculationNode::create(offset().length())));
|
||||
} else {
|
||||
// FIXME: Flip calculated offsets (convert CSSMathValue to CalculationNode, then negate and append)
|
||||
return to_string(CSSStyleValue::SerializationMode::Normal);
|
||||
}
|
||||
auto flipped_absolute = CSSMathValue::create(SumCalculationNode::create(move(sum_parts)), CSSNumericType(CSSNumericType::BaseType::Length, 1));
|
||||
return flipped_absolute->to_string(mode);
|
||||
}
|
||||
return offset().to_string();
|
||||
}
|
||||
|
||||
StringBuilder builder;
|
||||
|
||||
if (m_properties.edge.has_value())
|
||||
builder.append(CSS::to_string(m_properties.edge.value()));
|
||||
|
||||
if (m_properties.edge.has_value() && m_properties.offset.has_value())
|
||||
builder.append(' ');
|
||||
|
||||
if (m_properties.offset.has_value())
|
||||
builder.append(m_properties.offset->to_string());
|
||||
|
||||
return builder.to_string_without_validation();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -14,31 +14,45 @@ namespace Web::CSS {
|
|||
|
||||
class EdgeStyleValue final : public StyleValueWithDefaultOperators<EdgeStyleValue> {
|
||||
public:
|
||||
static ValueComparingNonnullRefPtr<EdgeStyleValue> create(PositionEdge edge, LengthPercentage const& offset)
|
||||
static ValueComparingNonnullRefPtr<EdgeStyleValue> create(Optional<PositionEdge> edge, Optional<LengthPercentage> const& offset)
|
||||
{
|
||||
VERIFY(edge != PositionEdge::Center);
|
||||
return adopt_ref(*new (nothrow) EdgeStyleValue(edge, offset));
|
||||
}
|
||||
virtual ~EdgeStyleValue() override = default;
|
||||
|
||||
// NOTE: `center` is converted to `left 50%` or `top 50%` in parsing, so is never returned here.
|
||||
PositionEdge edge() const { return m_properties.edge; }
|
||||
LengthPercentage const& offset() const { return m_properties.offset; }
|
||||
Optional<PositionEdge> edge() const
|
||||
{
|
||||
if (m_properties.edge == PositionEdge::Center)
|
||||
return {};
|
||||
|
||||
return m_properties.edge;
|
||||
}
|
||||
|
||||
LengthPercentage offset() const
|
||||
{
|
||||
if (m_properties.edge == PositionEdge::Center)
|
||||
return Percentage(50);
|
||||
|
||||
if (!m_properties.offset.has_value())
|
||||
return Percentage(0);
|
||||
|
||||
return m_properties.offset.value();
|
||||
}
|
||||
|
||||
virtual String to_string(SerializationMode) const override;
|
||||
|
||||
bool properties_equal(EdgeStyleValue const& other) const { return m_properties == other.m_properties; }
|
||||
|
||||
private:
|
||||
EdgeStyleValue(PositionEdge edge, LengthPercentage const& offset)
|
||||
EdgeStyleValue(Optional<PositionEdge> edge, Optional<LengthPercentage> const& offset)
|
||||
: StyleValueWithDefaultOperators(Type::Edge)
|
||||
, m_properties { .edge = edge, .offset = offset }
|
||||
{
|
||||
}
|
||||
|
||||
struct Properties {
|
||||
PositionEdge edge;
|
||||
LengthPercentage offset;
|
||||
Optional<PositionEdge> edge;
|
||||
Optional<LengthPercentage> offset;
|
||||
bool operator==(Properties const&) const = default;
|
||||
} m_properties;
|
||||
};
|
||||
|
|
|
@ -13,10 +13,8 @@ namespace Web::CSS {
|
|||
|
||||
bool PositionStyleValue::is_center() const
|
||||
{
|
||||
return (edge_x()->edge() == PositionEdge::Left
|
||||
&& edge_x()->offset().is_percentage() && edge_x()->offset().percentage() == Percentage { 50 })
|
||||
&& (edge_y()->edge() == PositionEdge::Top
|
||||
&& edge_y()->offset().is_percentage() && edge_y()->offset().percentage() == Percentage { 50 });
|
||||
return (edge_x()->offset().is_percentage() && edge_x()->offset().percentage() == Percentage { 50 })
|
||||
&& (edge_y()->offset().is_percentage() && edge_y()->offset().percentage() == Percentage { 50 });
|
||||
}
|
||||
|
||||
CSSPixelPoint PositionStyleValue::resolved(Layout::Node const& node, CSSPixelRect const& rect) const
|
||||
|
|
|
@ -25,8 +25,8 @@ public:
|
|||
static ValueComparingNonnullRefPtr<PositionStyleValue> create_center()
|
||||
{
|
||||
return adopt_ref(*new (nothrow) PositionStyleValue(
|
||||
EdgeStyleValue::create(PositionEdge::Left, Percentage { 50 }),
|
||||
EdgeStyleValue::create(PositionEdge::Top, Percentage { 50 })));
|
||||
EdgeStyleValue::create(PositionEdge::Center, {}),
|
||||
EdgeStyleValue::create(PositionEdge::Center, {})));
|
||||
}
|
||||
virtual ~PositionStyleValue() override = default;
|
||||
|
||||
|
|
|
@ -65,6 +65,8 @@ String ShorthandStyleValue::to_string(SerializationMode mode) const
|
|||
auto color = longhand(PropertyID::BackgroundColor);
|
||||
auto image = longhand(PropertyID::BackgroundImage);
|
||||
auto position = longhand(PropertyID::BackgroundPosition);
|
||||
auto position_x = position->as_shorthand().longhand(PropertyID::BackgroundPositionX);
|
||||
auto position_y = position->as_shorthand().longhand(PropertyID::BackgroundPositionY);
|
||||
auto size = longhand(PropertyID::BackgroundSize);
|
||||
auto repeat = longhand(PropertyID::BackgroundRepeat);
|
||||
auto attachment = longhand(PropertyID::BackgroundAttachment);
|
||||
|
@ -75,10 +77,10 @@ String ShorthandStyleValue::to_string(SerializationMode mode) const
|
|||
return style_value->is_value_list() ? style_value->as_value_list().size() : 1;
|
||||
};
|
||||
|
||||
auto layer_count = max(get_layer_count(image), max(get_layer_count(position), max(get_layer_count(size), max(get_layer_count(repeat), max(get_layer_count(attachment), max(get_layer_count(origin), get_layer_count(clip)))))));
|
||||
auto layer_count = max(get_layer_count(image), max(get_layer_count(position_x), max(get_layer_count(position_y), max(get_layer_count(size), max(get_layer_count(repeat), max(get_layer_count(attachment), max(get_layer_count(origin), get_layer_count(clip))))))));
|
||||
|
||||
if (layer_count == 1) {
|
||||
return MUST(String::formatted("{} {} {} {} {} {} {} {}", color->to_string(mode), image->to_string(mode), position->to_string(mode), size->to_string(mode), repeat->to_string(mode), attachment->to_string(mode), origin->to_string(mode), clip->to_string(mode)));
|
||||
return MUST(String::formatted("{} {} {} {} {} {} {} {} {}", color->to_string(mode), image->to_string(mode), position_x->to_string(mode), position_y->to_string(mode), size->to_string(mode), repeat->to_string(mode), attachment->to_string(mode), origin->to_string(mode), clip->to_string(mode)));
|
||||
}
|
||||
|
||||
auto get_layer_value_string = [mode](ValueComparingRefPtr<CSSStyleValue const> const& style_value, size_t index) {
|
||||
|
@ -93,7 +95,38 @@ String ShorthandStyleValue::to_string(SerializationMode mode) const
|
|||
builder.append(", "sv);
|
||||
if (i == layer_count - 1)
|
||||
builder.appendff("{} ", color->to_string(mode));
|
||||
builder.appendff("{} {} {} {} {} {} {}", get_layer_value_string(image, i), get_layer_value_string(position, i), get_layer_value_string(size, i), get_layer_value_string(repeat, i), get_layer_value_string(attachment, i), get_layer_value_string(origin, i), get_layer_value_string(clip, i));
|
||||
builder.appendff("{} {} {} {} {} {} {} {}", get_layer_value_string(image, i), get_layer_value_string(position_x, i), get_layer_value_string(position_y, i), get_layer_value_string(size, i), get_layer_value_string(repeat, i), get_layer_value_string(attachment, i), get_layer_value_string(origin, i), get_layer_value_string(clip, i));
|
||||
}
|
||||
|
||||
return MUST(builder.to_string());
|
||||
}
|
||||
case Web::CSS::PropertyID::BackgroundPosition: {
|
||||
auto x_edges = longhand(PropertyID::BackgroundPositionX);
|
||||
auto y_edges = longhand(PropertyID::BackgroundPositionY);
|
||||
|
||||
auto get_layer_count = [](auto style_value) -> size_t {
|
||||
return style_value->is_value_list() ? style_value->as_value_list().size() : 1;
|
||||
};
|
||||
|
||||
// FIXME: The spec is unclear about how differing layer counts should be handled
|
||||
auto layer_count = max(get_layer_count(x_edges), get_layer_count(y_edges));
|
||||
|
||||
if (layer_count == 1) {
|
||||
return MUST(String::formatted("{} {}", x_edges->to_string(mode), y_edges->to_string(mode)));
|
||||
}
|
||||
|
||||
auto get_layer_value_string = [mode](ValueComparingRefPtr<CSSStyleValue const> const& style_value, size_t index) {
|
||||
if (style_value->is_value_list())
|
||||
return style_value->as_value_list().value_at(index, true)->to_string(mode);
|
||||
return style_value->to_string(mode);
|
||||
};
|
||||
|
||||
StringBuilder builder;
|
||||
for (size_t i = 0; i < layer_count; i++) {
|
||||
if (i)
|
||||
builder.append(", "sv);
|
||||
|
||||
builder.appendff("{} {}", get_layer_value_string(x_edges, i), get_layer_value_string(y_edges, i));
|
||||
}
|
||||
|
||||
return MUST(builder.to_string());
|
||||
|
|
|
@ -428,13 +428,13 @@ void NodeWithStyle::apply_style(const CSS::StyleProperties& computed_style)
|
|||
|
||||
if (auto position_value = value_for_layer(x_positions, layer_index); position_value && position_value->is_edge()) {
|
||||
auto& position = position_value->as_edge();
|
||||
layer.position_edge_x = position.edge();
|
||||
layer.position_edge_x = position.edge().value_or(CSS::PositionEdge::Left);
|
||||
layer.position_offset_x = position.offset();
|
||||
}
|
||||
|
||||
if (auto position_value = value_for_layer(y_positions, layer_index); position_value && position_value->is_edge()) {
|
||||
auto& position = position_value->as_edge();
|
||||
layer.position_edge_y = position.edge();
|
||||
layer.position_edge_y = position.edge().value_or(CSS::PositionEdge::Top);
|
||||
layer.position_offset_y = position.offset();
|
||||
};
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
style.cssText = background-color: yellow; background-image: none; background-position-x: left 0%; background-position-y: top 0%; background-size: auto auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box;
|
||||
style.cssText = background-color: yellow; background-image: none; background-position-x: 0%; background-position-y: 0%; background-size: auto auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box;
|
||||
style.length = 9
|
||||
style[] =
|
||||
1. background-color
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
right 0px
|
||||
bottom 0px
|
||||
100%
|
||||
100%
|
||||
|
|
|
@ -159,7 +159,7 @@ All supported properties and their default values exposed from CSSStyleDeclarati
|
|||
'aspect-ratio': 'auto'
|
||||
'backdropFilter': 'none'
|
||||
'backdrop-filter': 'none'
|
||||
'background': 'rgba(0, 0, 0, 0) none left 0% top 0% auto auto repeat scroll padding-box border-box'
|
||||
'background': 'rgba(0, 0, 0, 0) none 0% 0% auto auto repeat scroll padding-box border-box'
|
||||
'backgroundAttachment': 'scroll'
|
||||
'background-attachment': 'scroll'
|
||||
'backgroundClip': 'border-box'
|
||||
|
@ -170,12 +170,12 @@ All supported properties and their default values exposed from CSSStyleDeclarati
|
|||
'background-image': 'none'
|
||||
'backgroundOrigin': 'padding-box'
|
||||
'background-origin': 'padding-box'
|
||||
'backgroundPosition': 'left 0% top 0%'
|
||||
'background-position': 'left 0% top 0%'
|
||||
'backgroundPositionX': 'left 0%'
|
||||
'background-position-x': 'left 0%'
|
||||
'backgroundPositionY': 'top 0%'
|
||||
'background-position-y': 'top 0%'
|
||||
'backgroundPosition': '0% 0%'
|
||||
'background-position': '0% 0%'
|
||||
'backgroundPositionX': '0%'
|
||||
'background-position-x': '0%'
|
||||
'backgroundPositionY': '0%'
|
||||
'background-position-y': '0%'
|
||||
'backgroundRepeat': 'repeat'
|
||||
'background-repeat': 'repeat'
|
||||
'backgroundSize': 'auto auto'
|
||||
|
@ -430,8 +430,8 @@ All supported properties and their default values exposed from CSSStyleDeclarati
|
|||
'min-width': 'auto'
|
||||
'objectFit': 'fill'
|
||||
'object-fit': 'fill'
|
||||
'objectPosition': 'left 50% top 50%'
|
||||
'object-position': 'left 50% top 50%'
|
||||
'objectPosition': '50% 50%'
|
||||
'object-position': '50% 50%'
|
||||
'opacity': '1'
|
||||
'order': '0'
|
||||
'outline': 'rgb(0, 0, 0) none medium'
|
||||
|
|
|
@ -8,10 +8,10 @@ backdrop-filter: 'grayscale(calc(2%))' -> 'grayscale(calc(2%))'
|
|||
backdrop-filter: 'grayscale(calc(2% * var(--n)))' -> 'grayscale(calc(2% * 2))'
|
||||
backdrop-filter: 'grayscale(calc(0.02))' -> 'grayscale(calc(0.02))'
|
||||
backdrop-filter: 'grayscale(calc(0.02 * var(--n)))' -> 'grayscale(calc(0.02 * 2))'
|
||||
background-position-x: 'calc(2px)' -> 'left calc(2px)'
|
||||
background-position-x: 'calc(2px * var(--n))' -> 'left calc(2px * 2)'
|
||||
background-position-y: 'calc(2%)' -> 'top calc(2%)'
|
||||
background-position-y: 'calc(2% * var(--n))' -> 'top 4%'
|
||||
background-position-x: 'calc(2px)' -> 'calc(2px)'
|
||||
background-position-x: 'calc(2px * var(--n))' -> 'calc(2px * 2)'
|
||||
background-position-y: 'calc(2%)' -> 'calc(2%)'
|
||||
background-position-y: 'calc(2% * var(--n))' -> '4%'
|
||||
background-size: 'calc(2px * var(--n)) calc(2%)' -> 'calc(2px * 2) 2%'
|
||||
background-size: 'calc(2px * var(--n)) calc(2% * var(--n))' -> 'calc(2px * 2) 4%'
|
||||
border-bottom-left-radius: 'calc(2px)' -> 'calc(2px)'
|
||||
|
|
|
@ -71,8 +71,8 @@ background-clip: border-box
|
|||
background-color: rgba(0, 0, 0, 0)
|
||||
background-image: none
|
||||
background-origin: padding-box
|
||||
background-position-x: left 0%
|
||||
background-position-y: top 0%
|
||||
background-position-x: 0%
|
||||
background-position-y: 0%
|
||||
background-repeat: repeat
|
||||
background-size: auto auto
|
||||
border-bottom-color: rgb(0, 0, 0)
|
||||
|
@ -154,7 +154,7 @@ min-height: auto
|
|||
min-inline-size: 0px
|
||||
min-width: auto
|
||||
object-fit: fill
|
||||
object-position: left 50% top 50%
|
||||
object-position: 50% 50%
|
||||
opacity: 1
|
||||
order: 0
|
||||
outline-color: rgb(0, 0, 0)
|
||||
|
|
18
Tests/LibWeb/Text/expected/position-serialization.txt
Normal file
18
Tests/LibWeb/Text/expected/position-serialization.txt
Normal file
|
@ -0,0 +1,18 @@
|
|||
inline: center center
|
||||
computed: 50% 50%
|
||||
inline: left bottom
|
||||
computed: 0% 100%
|
||||
inline: center top
|
||||
computed: 50% 0%
|
||||
inline: center top 20%
|
||||
computed: 50% 20%
|
||||
inline: left 10px top 20%
|
||||
computed: 10px 20%
|
||||
inline: 10px top
|
||||
computed: 10px 0%
|
||||
inline: right 10px bottom 20%
|
||||
computed: calc(100% + (0 - 10px)) 80%
|
||||
inline: center center, left bottom
|
||||
computed: 50% 50%, 0% 100%
|
||||
inline: left 10px bottom 20%, right 10px top 20%
|
||||
computed: 10px 80%, calc(100% + (0 - 10px)) 20%
|
|
@ -0,0 +1,36 @@
|
|||
Harness status: OK
|
||||
|
||||
Found 31 tests
|
||||
|
||||
31 Pass
|
||||
Pass e.style['background-position'] = "1px" should set the property value
|
||||
Pass e.style['background-position'] = "1px center" should set the property value
|
||||
Pass e.style['background-position'] = "-2% -3%" should set the property value
|
||||
Pass e.style['background-position'] = "5% top" should set the property value
|
||||
Pass e.style['background-position'] = "center" should set the property value
|
||||
Pass e.style['background-position'] = "center center" should set the property value
|
||||
Pass e.style['background-position'] = "center 6px" should set the property value
|
||||
Pass e.style['background-position'] = "center left" should set the property value
|
||||
Pass e.style['background-position'] = "center right 7%" should set the property value
|
||||
Pass e.style['background-position'] = "center bottom" should set the property value
|
||||
Pass e.style['background-position'] = "center top 8px" should set the property value
|
||||
Pass e.style['background-position'] = "left" should set the property value
|
||||
Pass e.style['background-position'] = "right 9%" should set the property value
|
||||
Pass e.style['background-position'] = "left 10px center" should set the property value
|
||||
Pass e.style['background-position'] = "right 11% bottom" should set the property value
|
||||
Pass e.style['background-position'] = "left 12px top 13px" should set the property value
|
||||
Pass e.style['background-position'] = "right center" should set the property value
|
||||
Pass e.style['background-position'] = "left bottom" should set the property value
|
||||
Pass e.style['background-position'] = "right top 14%" should set the property value
|
||||
Pass e.style['background-position'] = "bottom" should set the property value
|
||||
Pass e.style['background-position'] = "top 15px center" should set the property value
|
||||
Pass e.style['background-position'] = "bottom 16% left" should set the property value
|
||||
Pass e.style['background-position'] = "top 17px right 18px" should set the property value
|
||||
Pass e.style['background-position'] = "bottom center" should set the property value
|
||||
Pass e.style['background-position'] = "top left" should set the property value
|
||||
Pass e.style['background-position'] = "bottom right 19%" should set the property value
|
||||
Pass e.style['background-position'] = "20% 0%" should set the property value
|
||||
Pass e.style['background-position'] = "0% 0%" should set the property value
|
||||
Pass e.style['background-position'] = "0%" should set the property value
|
||||
Pass e.style['background-position'] = "0% center" should set the property value
|
||||
Pass e.style['background-position'] = "center 0%" should set the property value
|
|
@ -2,8 +2,8 @@ Harness status: OK
|
|||
|
||||
Found 687 tests
|
||||
|
||||
485 Pass
|
||||
202 Fail
|
||||
654 Pass
|
||||
33 Fail
|
||||
Pass background-attachment: scroll
|
||||
Pass background-attachment: fixed
|
||||
Pass background-attachment: inherit
|
||||
|
@ -17,175 +17,175 @@ Pass background-image: url("http://localhost/")
|
|||
Pass background-image: url(http://localhost/)
|
||||
Pass background-image: none
|
||||
Pass background-image: inherit
|
||||
Fail background-position: 5% 5%
|
||||
Fail background-position: 5% .5%
|
||||
Fail background-position: 5% -5%
|
||||
Fail background-position: 5% -.5%
|
||||
Fail background-position: 5% 0px
|
||||
Fail background-position: 5% 1px
|
||||
Fail background-position: 5% .1em
|
||||
Fail background-position: 5% -0px
|
||||
Fail background-position: 5% -1px
|
||||
Fail background-position: 5% -.1em
|
||||
Fail background-position: 5% top
|
||||
Fail background-position: 5% center
|
||||
Fail background-position: 5% bottom
|
||||
Fail background-position: .5% 5%
|
||||
Fail background-position: .5% .5%
|
||||
Fail background-position: .5% -5%
|
||||
Fail background-position: .5% -.5%
|
||||
Fail background-position: .5% 0px
|
||||
Fail background-position: .5% 1px
|
||||
Fail background-position: .5% .1em
|
||||
Fail background-position: .5% -0px
|
||||
Fail background-position: .5% -1px
|
||||
Fail background-position: .5% -.1em
|
||||
Fail background-position: .5% top
|
||||
Fail background-position: .5% center
|
||||
Fail background-position: .5% bottom
|
||||
Fail background-position: -5% 5%
|
||||
Fail background-position: -5% .5%
|
||||
Fail background-position: -5% -5%
|
||||
Fail background-position: -5% -.5%
|
||||
Fail background-position: -5% 0px
|
||||
Fail background-position: -5% 1px
|
||||
Fail background-position: -5% .1em
|
||||
Fail background-position: -5% -0px
|
||||
Fail background-position: -5% -1px
|
||||
Fail background-position: -5% -.1em
|
||||
Fail background-position: -5% top
|
||||
Fail background-position: -5% center
|
||||
Fail background-position: -5% bottom
|
||||
Fail background-position: -.5% 5%
|
||||
Fail background-position: -.5% .5%
|
||||
Fail background-position: -.5% -5%
|
||||
Fail background-position: -.5% -.5%
|
||||
Fail background-position: -.5% 0px
|
||||
Fail background-position: -.5% 1px
|
||||
Fail background-position: -.5% .1em
|
||||
Fail background-position: -.5% -0px
|
||||
Fail background-position: -.5% -1px
|
||||
Fail background-position: -.5% -.1em
|
||||
Fail background-position: -.5% top
|
||||
Fail background-position: -.5% center
|
||||
Fail background-position: -.5% bottom
|
||||
Fail background-position: 0px 5%
|
||||
Fail background-position: 0px .5%
|
||||
Fail background-position: 0px -5%
|
||||
Fail background-position: 0px -.5%
|
||||
Fail background-position: 0px 0px
|
||||
Fail background-position: 0px 1px
|
||||
Fail background-position: 0px .1em
|
||||
Fail background-position: 0px -0px
|
||||
Fail background-position: 0px -1px
|
||||
Fail background-position: 0px -.1em
|
||||
Fail background-position: 0px top
|
||||
Fail background-position: 0px center
|
||||
Fail background-position: 0px bottom
|
||||
Fail background-position: 1px 5%
|
||||
Fail background-position: 1px .5%
|
||||
Fail background-position: 1px -5%
|
||||
Fail background-position: 1px -.5%
|
||||
Fail background-position: 1px 0px
|
||||
Fail background-position: 1px 1px
|
||||
Fail background-position: 1px .1em
|
||||
Fail background-position: 1px -0px
|
||||
Fail background-position: 1px -1px
|
||||
Fail background-position: 1px -.1em
|
||||
Fail background-position: 1px top
|
||||
Fail background-position: 1px center
|
||||
Fail background-position: 1px bottom
|
||||
Fail background-position: .1em 5%
|
||||
Fail background-position: .1em .5%
|
||||
Fail background-position: .1em -5%
|
||||
Fail background-position: .1em -.5%
|
||||
Fail background-position: .1em 0px
|
||||
Fail background-position: .1em 1px
|
||||
Fail background-position: .1em .1em
|
||||
Fail background-position: .1em -0px
|
||||
Fail background-position: .1em -1px
|
||||
Fail background-position: .1em -.1em
|
||||
Fail background-position: .1em top
|
||||
Fail background-position: .1em center
|
||||
Fail background-position: .1em bottom
|
||||
Fail background-position: -0px 5%
|
||||
Fail background-position: -0px .5%
|
||||
Fail background-position: -0px -5%
|
||||
Fail background-position: -0px -.5%
|
||||
Fail background-position: -0px 0px
|
||||
Fail background-position: -0px 1px
|
||||
Fail background-position: -0px .1em
|
||||
Fail background-position: -0px -0px
|
||||
Fail background-position: -0px -1px
|
||||
Fail background-position: -0px -.1em
|
||||
Fail background-position: -0px top
|
||||
Fail background-position: -0px center
|
||||
Fail background-position: -0px bottom
|
||||
Fail background-position: -1px 5%
|
||||
Fail background-position: -1px .5%
|
||||
Fail background-position: -1px -5%
|
||||
Fail background-position: -1px -.5%
|
||||
Fail background-position: -1px 0px
|
||||
Fail background-position: -1px 1px
|
||||
Fail background-position: -1px .1em
|
||||
Fail background-position: -1px -0px
|
||||
Fail background-position: -1px -1px
|
||||
Fail background-position: -1px -.1em
|
||||
Fail background-position: -1px top
|
||||
Fail background-position: -1px center
|
||||
Fail background-position: -1px bottom
|
||||
Fail background-position: -.1em 5%
|
||||
Fail background-position: -.1em .5%
|
||||
Fail background-position: -.1em -5%
|
||||
Fail background-position: -.1em -.5%
|
||||
Fail background-position: -.1em 0px
|
||||
Fail background-position: -.1em 1px
|
||||
Fail background-position: -.1em .1em
|
||||
Fail background-position: -.1em -0px
|
||||
Fail background-position: -.1em -1px
|
||||
Fail background-position: -.1em -.1em
|
||||
Fail background-position: -.1em top
|
||||
Fail background-position: -.1em center
|
||||
Fail background-position: -.1em bottom
|
||||
Fail background-position: left 5%
|
||||
Fail background-position: left .5%
|
||||
Fail background-position: left -5%
|
||||
Fail background-position: left -.5%
|
||||
Fail background-position: left 0px
|
||||
Fail background-position: left 1px
|
||||
Fail background-position: left .1em
|
||||
Fail background-position: left -0px
|
||||
Fail background-position: left -1px
|
||||
Fail background-position: left -.1em
|
||||
Fail background-position: left top
|
||||
Fail background-position: left center
|
||||
Fail background-position: left bottom
|
||||
Fail background-position: center 5%
|
||||
Fail background-position: center .5%
|
||||
Fail background-position: center -5%
|
||||
Fail background-position: center -.5%
|
||||
Fail background-position: center 0px
|
||||
Fail background-position: center 1px
|
||||
Fail background-position: center .1em
|
||||
Fail background-position: center -0px
|
||||
Fail background-position: center -1px
|
||||
Fail background-position: center -.1em
|
||||
Fail background-position: center top
|
||||
Fail background-position: center center
|
||||
Fail background-position: center bottom
|
||||
Fail background-position: right 5%
|
||||
Fail background-position: right .5%
|
||||
Fail background-position: right -5%
|
||||
Fail background-position: right -.5%
|
||||
Fail background-position: right 0px
|
||||
Fail background-position: right 1px
|
||||
Fail background-position: right .1em
|
||||
Fail background-position: right -0px
|
||||
Fail background-position: right -1px
|
||||
Fail background-position: right -.1em
|
||||
Fail background-position: right top
|
||||
Fail background-position: right center
|
||||
Fail background-position: right bottom
|
||||
Pass background-position: 5% 5%
|
||||
Pass background-position: 5% .5%
|
||||
Pass background-position: 5% -5%
|
||||
Pass background-position: 5% -.5%
|
||||
Pass background-position: 5% 0px
|
||||
Pass background-position: 5% 1px
|
||||
Pass background-position: 5% .1em
|
||||
Pass background-position: 5% -0px
|
||||
Pass background-position: 5% -1px
|
||||
Pass background-position: 5% -.1em
|
||||
Pass background-position: 5% top
|
||||
Pass background-position: 5% center
|
||||
Pass background-position: 5% bottom
|
||||
Pass background-position: .5% 5%
|
||||
Pass background-position: .5% .5%
|
||||
Pass background-position: .5% -5%
|
||||
Pass background-position: .5% -.5%
|
||||
Pass background-position: .5% 0px
|
||||
Pass background-position: .5% 1px
|
||||
Pass background-position: .5% .1em
|
||||
Pass background-position: .5% -0px
|
||||
Pass background-position: .5% -1px
|
||||
Pass background-position: .5% -.1em
|
||||
Pass background-position: .5% top
|
||||
Pass background-position: .5% center
|
||||
Pass background-position: .5% bottom
|
||||
Pass background-position: -5% 5%
|
||||
Pass background-position: -5% .5%
|
||||
Pass background-position: -5% -5%
|
||||
Pass background-position: -5% -.5%
|
||||
Pass background-position: -5% 0px
|
||||
Pass background-position: -5% 1px
|
||||
Pass background-position: -5% .1em
|
||||
Pass background-position: -5% -0px
|
||||
Pass background-position: -5% -1px
|
||||
Pass background-position: -5% -.1em
|
||||
Pass background-position: -5% top
|
||||
Pass background-position: -5% center
|
||||
Pass background-position: -5% bottom
|
||||
Pass background-position: -.5% 5%
|
||||
Pass background-position: -.5% .5%
|
||||
Pass background-position: -.5% -5%
|
||||
Pass background-position: -.5% -.5%
|
||||
Pass background-position: -.5% 0px
|
||||
Pass background-position: -.5% 1px
|
||||
Pass background-position: -.5% .1em
|
||||
Pass background-position: -.5% -0px
|
||||
Pass background-position: -.5% -1px
|
||||
Pass background-position: -.5% -.1em
|
||||
Pass background-position: -.5% top
|
||||
Pass background-position: -.5% center
|
||||
Pass background-position: -.5% bottom
|
||||
Pass background-position: 0px 5%
|
||||
Pass background-position: 0px .5%
|
||||
Pass background-position: 0px -5%
|
||||
Pass background-position: 0px -.5%
|
||||
Pass background-position: 0px 0px
|
||||
Pass background-position: 0px 1px
|
||||
Pass background-position: 0px .1em
|
||||
Pass background-position: 0px -0px
|
||||
Pass background-position: 0px -1px
|
||||
Pass background-position: 0px -.1em
|
||||
Pass background-position: 0px top
|
||||
Pass background-position: 0px center
|
||||
Pass background-position: 0px bottom
|
||||
Pass background-position: 1px 5%
|
||||
Pass background-position: 1px .5%
|
||||
Pass background-position: 1px -5%
|
||||
Pass background-position: 1px -.5%
|
||||
Pass background-position: 1px 0px
|
||||
Pass background-position: 1px 1px
|
||||
Pass background-position: 1px .1em
|
||||
Pass background-position: 1px -0px
|
||||
Pass background-position: 1px -1px
|
||||
Pass background-position: 1px -.1em
|
||||
Pass background-position: 1px top
|
||||
Pass background-position: 1px center
|
||||
Pass background-position: 1px bottom
|
||||
Pass background-position: .1em 5%
|
||||
Pass background-position: .1em .5%
|
||||
Pass background-position: .1em -5%
|
||||
Pass background-position: .1em -.5%
|
||||
Pass background-position: .1em 0px
|
||||
Pass background-position: .1em 1px
|
||||
Pass background-position: .1em .1em
|
||||
Pass background-position: .1em -0px
|
||||
Pass background-position: .1em -1px
|
||||
Pass background-position: .1em -.1em
|
||||
Pass background-position: .1em top
|
||||
Pass background-position: .1em center
|
||||
Pass background-position: .1em bottom
|
||||
Pass background-position: -0px 5%
|
||||
Pass background-position: -0px .5%
|
||||
Pass background-position: -0px -5%
|
||||
Pass background-position: -0px -.5%
|
||||
Pass background-position: -0px 0px
|
||||
Pass background-position: -0px 1px
|
||||
Pass background-position: -0px .1em
|
||||
Pass background-position: -0px -0px
|
||||
Pass background-position: -0px -1px
|
||||
Pass background-position: -0px -.1em
|
||||
Pass background-position: -0px top
|
||||
Pass background-position: -0px center
|
||||
Pass background-position: -0px bottom
|
||||
Pass background-position: -1px 5%
|
||||
Pass background-position: -1px .5%
|
||||
Pass background-position: -1px -5%
|
||||
Pass background-position: -1px -.5%
|
||||
Pass background-position: -1px 0px
|
||||
Pass background-position: -1px 1px
|
||||
Pass background-position: -1px .1em
|
||||
Pass background-position: -1px -0px
|
||||
Pass background-position: -1px -1px
|
||||
Pass background-position: -1px -.1em
|
||||
Pass background-position: -1px top
|
||||
Pass background-position: -1px center
|
||||
Pass background-position: -1px bottom
|
||||
Pass background-position: -.1em 5%
|
||||
Pass background-position: -.1em .5%
|
||||
Pass background-position: -.1em -5%
|
||||
Pass background-position: -.1em -.5%
|
||||
Pass background-position: -.1em 0px
|
||||
Pass background-position: -.1em 1px
|
||||
Pass background-position: -.1em .1em
|
||||
Pass background-position: -.1em -0px
|
||||
Pass background-position: -.1em -1px
|
||||
Pass background-position: -.1em -.1em
|
||||
Pass background-position: -.1em top
|
||||
Pass background-position: -.1em center
|
||||
Pass background-position: -.1em bottom
|
||||
Pass background-position: left 5%
|
||||
Pass background-position: left .5%
|
||||
Pass background-position: left -5%
|
||||
Pass background-position: left -.5%
|
||||
Pass background-position: left 0px
|
||||
Pass background-position: left 1px
|
||||
Pass background-position: left .1em
|
||||
Pass background-position: left -0px
|
||||
Pass background-position: left -1px
|
||||
Pass background-position: left -.1em
|
||||
Pass background-position: left top
|
||||
Pass background-position: left center
|
||||
Pass background-position: left bottom
|
||||
Pass background-position: center 5%
|
||||
Pass background-position: center .5%
|
||||
Pass background-position: center -5%
|
||||
Pass background-position: center -.5%
|
||||
Pass background-position: center 0px
|
||||
Pass background-position: center 1px
|
||||
Pass background-position: center .1em
|
||||
Pass background-position: center -0px
|
||||
Pass background-position: center -1px
|
||||
Pass background-position: center -.1em
|
||||
Pass background-position: center top
|
||||
Pass background-position: center center
|
||||
Pass background-position: center bottom
|
||||
Pass background-position: right 5%
|
||||
Pass background-position: right .5%
|
||||
Pass background-position: right -5%
|
||||
Pass background-position: right -.5%
|
||||
Pass background-position: right 0px
|
||||
Pass background-position: right 1px
|
||||
Pass background-position: right .1em
|
||||
Pass background-position: right -0px
|
||||
Pass background-position: right -1px
|
||||
Pass background-position: right -.1em
|
||||
Pass background-position: right top
|
||||
Pass background-position: right center
|
||||
Pass background-position: right bottom
|
||||
Pass background-position: inherit
|
||||
Pass background-repeat: repeat
|
||||
Pass background-repeat: repeat-x
|
||||
|
|
25
Tests/LibWeb/Text/input/position-serialization.html
Normal file
25
Tests/LibWeb/Text/input/position-serialization.html
Normal file
|
@ -0,0 +1,25 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="include.js"></script>
|
||||
<div id="target"></div>
|
||||
<script>
|
||||
test(() => {
|
||||
const values = [
|
||||
"center",
|
||||
"left bottom",
|
||||
"center top",
|
||||
"center top 20%",
|
||||
"left 10px top 20%",
|
||||
"10px top",
|
||||
"right 10px bottom 20%",
|
||||
"center, left bottom",
|
||||
"left 10px bottom 20%, right 10px top 20%"
|
||||
];
|
||||
|
||||
const target = document.getElementById('target');
|
||||
for (const value of values) {
|
||||
target.style.setProperty("background-position", value);
|
||||
println("inline: " + target.style.getPropertyValue("background-position"));
|
||||
println("computed: " + getComputedStyle(target).getPropertyValue("background-position"));
|
||||
}
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1,48 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Backgrounds and Borders Module Level 3: parsing background-position with valid values</title>
|
||||
<link rel="author" title="Eric Willigers" href="mailto:ericwilligers@chromium.org">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-backgrounds/#background-position">
|
||||
<meta name="assert" content="background-position supports the full grammar '<bg-position>'.">
|
||||
<script src="../../../resources/testharness.js"></script>
|
||||
<script src="../../../resources/testharnessreport.js"></script>
|
||||
<script src="../../../css/support/parsing-testcommon.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
test_valid_value("background-position", "1px", ["1px", "1px center"]);
|
||||
test_valid_value("background-position", "1px center", ["1px", "1px center"]);
|
||||
test_valid_value("background-position", "-2% -3%");
|
||||
test_valid_value("background-position", "5% top");
|
||||
test_valid_value("background-position", "center", ["center", "center center"]);
|
||||
test_valid_value("background-position", "center center", ["center", "center center"]);
|
||||
test_valid_value("background-position", "center 6px");
|
||||
test_valid_value("background-position", "center left", ["left center", "left"]);
|
||||
test_valid_value("background-position", "center right 7%", "right 7% center");
|
||||
test_valid_value("background-position", "center bottom", ["center bottom", "bottom"]);
|
||||
test_valid_value("background-position", "center top 8px", ["center top 8px", "center 8px"]);
|
||||
test_valid_value("background-position", "left", ["left center", "left"]);
|
||||
test_valid_value("background-position", "right 9%");
|
||||
test_valid_value("background-position", "left 10px center", ["left 10px center", "10px"]);
|
||||
test_valid_value("background-position", "right 11% bottom", ["right 11% bottom", "right 11% bottom 0%"]); // "right 11% bottom 0%" in Edge
|
||||
test_valid_value("background-position", "left 12px top 13px", ["left 12px top 13px", "12px 13px"]);
|
||||
test_valid_value("background-position", "right center", ["right center", "right"]);
|
||||
test_valid_value("background-position", "left bottom");
|
||||
test_valid_value("background-position", "right top 14%", ["right top 14%", "right 14%"]);
|
||||
test_valid_value("background-position", "bottom", ["center bottom", "bottom"]);
|
||||
test_valid_value("background-position", "top 15px center", ["center top 15px", "center 15px"]);
|
||||
test_valid_value("background-position", "bottom 16% left", ["left bottom 16%", "left 0% bottom 16%"]); // "left 0% bottom 16%" in Edge
|
||||
test_valid_value("background-position", "top 17px right 18px", "right 18px top 17px");
|
||||
test_valid_value("background-position", "bottom center", ["center bottom", "bottom"]);
|
||||
test_valid_value("background-position", "top left", "left top");
|
||||
test_valid_value("background-position", "bottom right 19%", ["right 19% bottom", "right 19% bottom 0%"]); // "right 19% bottom 0%" in Edge
|
||||
test_valid_value("background-position", "20% 0%");
|
||||
test_valid_value("background-position", "0% 0%");
|
||||
test_valid_value("background-position", "0%", ["0%", "0% center"]);
|
||||
test_valid_value("background-position", "0% center", ["0%", "0% center"]);
|
||||
test_valid_value("background-position", "center 0%");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in a new issue