diff options
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/ComputedValues.h | 9 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/Properties.json | 14 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/StyleProperties.cpp | 28 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/StyleProperties.h | 3 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/StyleResolver.cpp | 71 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/StyleValue.h | 2 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/DOM/Document.cpp | 17 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/DOM/Document.h | 3 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Layout/Box.cpp | 26 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Layout/Box.h | 2 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Layout/InitialContainingBlockBox.cpp | 2 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Layout/Node.cpp | 10 |
12 files changed, 152 insertions, 35 deletions
diff --git a/Userland/Libraries/LibWeb/CSS/ComputedValues.h b/Userland/Libraries/LibWeb/CSS/ComputedValues.h index 6035651bbb..6e3f8526e9 100644 --- a/Userland/Libraries/LibWeb/CSS/ComputedValues.h +++ b/Userland/Libraries/LibWeb/CSS/ComputedValues.h @@ -92,7 +92,8 @@ public: Color color() const { return m_inherited.color; } Color background_color() const { return m_noninherited.background_color; } - CSS::Repeat background_repeat() const { return m_noninherited.background_repeat; } + CSS::Repeat background_repeat_x() const { return m_noninherited.background_repeat_x; } + CSS::Repeat background_repeat_y() const { return m_noninherited.background_repeat_y; } CSS::ListStyleType list_style_type() const { return m_inherited.list_style_type; } @@ -134,7 +135,8 @@ protected: BorderData border_right; BorderData border_bottom; Color background_color { InitialValues::background_color() }; - CSS::Repeat background_repeat { InitialValues::background_repeat() }; + CSS::Repeat background_repeat_x { InitialValues::background_repeat() }; + CSS::Repeat background_repeat_y { InitialValues::background_repeat() }; CSS::FlexDirection flex_direction { InitialValues::flex_direction() }; CSS::Overflow overflow_x { InitialValues::overflow() }; CSS::Overflow overflow_y { InitialValues::overflow() }; @@ -149,7 +151,8 @@ public: void set_color(const Color& color) { m_inherited.color = color; } void set_cursor(CSS::Cursor cursor) { m_inherited.cursor = cursor; } void set_background_color(const Color& color) { m_noninherited.background_color = color; } - void set_background_repeat(CSS::Repeat repeat) { m_noninherited.background_repeat = repeat; } + void set_background_repeat_x(CSS::Repeat repeat) { m_noninherited.background_repeat_x = repeat; } + void set_background_repeat_y(CSS::Repeat repeat) { m_noninherited.background_repeat_y = repeat; } void set_float(CSS::Float value) { m_noninherited.float_ = value; } void set_clear(CSS::Clear value) { m_noninherited.clear = value; } void set_z_index(Optional<int> value) { m_noninherited.z_index = value; } diff --git a/Userland/Libraries/LibWeb/CSS/Properties.json b/Userland/Libraries/LibWeb/CSS/Properties.json index 3fa5add4f5..3344ea6538 100644 --- a/Userland/Libraries/LibWeb/CSS/Properties.json +++ b/Userland/Libraries/LibWeb/CSS/Properties.json @@ -18,8 +18,20 @@ "initial": "0% 0%" }, "background-repeat": { + "longhands": [ + "background-repeat-x", + "background-repeat-y" + ] + }, + "background-repeat-x": { + "inherited": false, + "initial": "repeat", + "pseudo": true + }, + "background-repeat-y": { "inherited": false, - "initial": "repeat" + "initial": "repeat", + "pseudo": true }, "border": { "longhands": [ diff --git a/Userland/Libraries/LibWeb/CSS/StyleProperties.cpp b/Userland/Libraries/LibWeb/CSS/StyleProperties.cpp index 539f1d05ea..5506f86fce 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleProperties.cpp +++ b/Userland/Libraries/LibWeb/CSS/StyleProperties.cpp @@ -612,9 +612,29 @@ Optional<CSS::Overflow> StyleProperties::overflow(CSS::PropertyID property_id) c } } -Optional<CSS::Repeat> StyleProperties::background_repeat() const +Optional<CSS::Repeat> StyleProperties::background_repeat_x() const { - auto value = property(CSS::PropertyID::BackgroundRepeat); + auto value = property(CSS::PropertyID::BackgroundRepeatX); + if (!value.has_value()) + return {}; + + switch (value.value()->to_identifier()) { + case CSS::ValueID::NoRepeat: + return CSS::Repeat::NoRepeat; + case CSS::ValueID::Repeat: + return CSS::Repeat::Repeat; + case CSS::ValueID::Round: + return CSS::Repeat::Round; + case CSS::ValueID::Space: + return CSS::Repeat::Space; + default: + return {}; + } +} + +Optional<CSS::Repeat> StyleProperties::background_repeat_y() const +{ + auto value = property(CSS::PropertyID::BackgroundRepeatY); if (!value.has_value()) return {}; @@ -623,10 +643,6 @@ Optional<CSS::Repeat> StyleProperties::background_repeat() const return CSS::Repeat::NoRepeat; case CSS::ValueID::Repeat: return CSS::Repeat::Repeat; - case CSS::ValueID::RepeatX: - return CSS::Repeat::RepeatX; - case CSS::ValueID::RepeatY: - return CSS::Repeat::RepeatY; case CSS::ValueID::Round: return CSS::Repeat::Round; case CSS::ValueID::Space: diff --git a/Userland/Libraries/LibWeb/CSS/StyleProperties.h b/Userland/Libraries/LibWeb/CSS/StyleProperties.h index 3bdadf24f1..e5a74528f3 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleProperties.h +++ b/Userland/Libraries/LibWeb/CSS/StyleProperties.h @@ -73,7 +73,8 @@ public: Optional<CSS::FlexDirection> flex_direction() const; Optional<CSS::Overflow> overflow_x() const; Optional<CSS::Overflow> overflow_y() const; - Optional<CSS::Repeat> background_repeat() const; + Optional<CSS::Repeat> background_repeat_x() const; + Optional<CSS::Repeat> background_repeat_y() const; const Gfx::Font& font() const { diff --git a/Userland/Libraries/LibWeb/CSS/StyleResolver.cpp b/Userland/Libraries/LibWeb/CSS/StyleResolver.cpp index d409100492..fb090d345c 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleResolver.cpp +++ b/Userland/Libraries/LibWeb/CSS/StyleResolver.cpp @@ -229,6 +229,24 @@ static inline void set_property_border_style(StyleProperties& style, const Style style.set_property(CSS::PropertyID::BorderLeftStyle, value); } +static inline bool is_background_repeat_property(const StyleValue& value) +{ + if (!value.is_identifier()) + return false; + + switch (value.to_identifier()) { + case CSS::ValueID::NoRepeat: + case CSS::ValueID::Repeat: + case CSS::ValueID::RepeatX: + case CSS::ValueID::RepeatY: + case CSS::ValueID::Round: + case CSS::ValueID::Space: + return true; + default: + return false; + } +} + static void set_property_expanding_shorthands(StyleProperties& style, CSS::PropertyID property_id, const StyleValue& value, DOM::Document& document, bool is_internally_generated_pseudo_property = false) { CSS::ParsingContext context(document); @@ -433,12 +451,22 @@ static void set_property_expanding_shorthands(StyleProperties& style, CSS::Prope if (values[0].is_color() && color_value_count == 1) style.set_property(CSS::PropertyID::BackgroundColor, values[0]); - for (auto& value : values) { - if (value.is_identifier()) - set_property_expanding_shorthands(style, CSS::PropertyID::BackgroundRepeat, value, document); + for (auto it = values.begin(); it != values.end(); ++it) { + auto& value = *it; + + if (is_background_repeat_property(value)) { + if ((it + 1 != values.end()) && is_background_repeat_property(*(it + 1))) { + ++it; + + set_property_expanding_shorthands(style, CSS::PropertyID::BackgroundRepeatX, value, document, true); + set_property_expanding_shorthands(style, CSS::PropertyID::BackgroundRepeatY, *it, document, true); + } else { + set_property_expanding_shorthands(style, CSS::PropertyID::BackgroundRepeat, value, document); + } + } + if (!value.is_string()) continue; - auto string = value.to_string(); set_property_expanding_shorthands(style, CSS::PropertyID::BackgroundImage, value, document); } return; @@ -464,7 +492,40 @@ static void set_property_expanding_shorthands(StyleProperties& style, CSS::Prope } if (property_id == CSS::PropertyID::BackgroundRepeat) { - style.set_property(CSS::PropertyID::BackgroundRepeat, value); + auto parts = split_on_whitespace(value.to_string()); + NonnullRefPtrVector<StyleValue> values; + for (auto& part : parts) { + auto value = parse_css_value(context, part); + if (!value || !is_background_repeat_property(*value)) + return; + values.append(value.release_nonnull()); + } + + if (values.size() == 1) { + auto value_id = values[0].to_identifier(); + if (value_id == CSS::ValueID::RepeatX || value_id == CSS::ValueID::RepeatY) { + auto repeat_x = IdentifierStyleValue::create(value_id == CSS::ValueID::RepeatX ? CSS::ValueID::Repeat : CSS::ValueID::NoRepeat); + auto repeat_y = IdentifierStyleValue::create(value_id == CSS::ValueID::RepeatX ? CSS::ValueID::NoRepeat : CSS::ValueID::Repeat); + set_property_expanding_shorthands(style, CSS::PropertyID::BackgroundRepeatX, repeat_x, document, true); + set_property_expanding_shorthands(style, CSS::PropertyID::BackgroundRepeatY, repeat_y, document, true); + } else { + set_property_expanding_shorthands(style, CSS::PropertyID::BackgroundRepeatX, values[0], document, true); + set_property_expanding_shorthands(style, CSS::PropertyID::BackgroundRepeatY, values[0], document, true); + } + } else if (values.size() == 2) { + set_property_expanding_shorthands(style, CSS::PropertyID::BackgroundRepeatX, values[0], document, true); + set_property_expanding_shorthands(style, CSS::PropertyID::BackgroundRepeatY, values[1], document, true); + } + + return; + } + + if (property_id == CSS::PropertyID::BackgroundRepeatX || property_id == CSS::PropertyID::BackgroundRepeatY) { + auto value_id = value.to_identifier(); + if (value_id == CSS::ValueID::RepeatX || value_id == CSS::ValueID::RepeatY) + return; + + style.set_property(property_id, value); return; } diff --git a/Userland/Libraries/LibWeb/CSS/StyleValue.h b/Userland/Libraries/LibWeb/CSS/StyleValue.h index aa8997786c..8cfd801595 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleValue.h +++ b/Userland/Libraries/LibWeb/CSS/StyleValue.h @@ -192,8 +192,6 @@ enum class Overflow : u8 { enum class Repeat : u8 { NoRepeat, Repeat, - RepeatX, - RepeatY, Round, Space, }; diff --git a/Userland/Libraries/LibWeb/DOM/Document.cpp b/Userland/Libraries/LibWeb/DOM/Document.cpp index de13a63f11..540f1adfd4 100644 --- a/Userland/Libraries/LibWeb/DOM/Document.cpp +++ b/Userland/Libraries/LibWeb/DOM/Document.cpp @@ -362,7 +362,7 @@ RefPtr<Gfx::Bitmap> Document::background_image() const return background_image->bitmap(); } -CSS::Repeat Document::background_repeat() const +CSS::Repeat Document::background_repeat_x() const { auto* body_element = body(); if (!body_element) @@ -372,7 +372,20 @@ CSS::Repeat Document::background_repeat() const if (!body_layout_node) return CSS::Repeat::Repeat; - return body_layout_node->computed_values().background_repeat(); + return body_layout_node->computed_values().background_repeat_x(); +} + +CSS::Repeat Document::background_repeat_y() const +{ + auto* body_element = body(); + if (!body_element) + return CSS::Repeat::Repeat; + + auto* body_layout_node = body_element->layout_node(); + if (!body_layout_node) + return CSS::Repeat::Repeat; + + return body_layout_node->computed_values().background_repeat_y(); } URL Document::complete_url(const String& string) const diff --git a/Userland/Libraries/LibWeb/DOM/Document.h b/Userland/Libraries/LibWeb/DOM/Document.h index d272db23f0..c42b43f8ef 100644 --- a/Userland/Libraries/LibWeb/DOM/Document.h +++ b/Userland/Libraries/LibWeb/DOM/Document.h @@ -129,7 +129,8 @@ public: Color background_color(const Gfx::Palette&) const; RefPtr<Gfx::Bitmap> background_image() const; - CSS::Repeat background_repeat() const; + CSS::Repeat background_repeat_x() const; + CSS::Repeat background_repeat_y() const; Color link_color() const; void set_link_color(Color); diff --git a/Userland/Libraries/LibWeb/Layout/Box.cpp b/Userland/Libraries/LibWeb/Layout/Box.cpp index 7e45d6a793..a9ff45e20c 100644 --- a/Userland/Libraries/LibWeb/Layout/Box.cpp +++ b/Userland/Libraries/LibWeb/Layout/Box.cpp @@ -50,7 +50,7 @@ void Box::paint(PaintContext& context, PaintPhase phase) context.painter().fill_rect(background_rect, computed_values().background_color()); if (background_image() && background_image()->bitmap()) { - paint_background_image(context, *background_image()->bitmap(), computed_values().background_repeat(), move(background_rect)); + paint_background_image(context, *background_image()->bitmap(), computed_values().background_repeat_x(), computed_values().background_repeat_y(), move(background_rect)); } } @@ -87,22 +87,30 @@ void Box::paint(PaintContext& context, PaintPhase phase) void Box::paint_background_image( PaintContext& context, const Gfx::Bitmap& background_image, - CSS::Repeat background_repeat, + CSS::Repeat background_repeat_x, + CSS::Repeat background_repeat_y, Gfx::IntRect background_rect) { - switch (background_repeat) { + switch (background_repeat_x) { + case CSS::Repeat::Round: + case CSS::Repeat::Space: + // FIXME: Support 'round' and 'space'. Fall through to 'repeat' since that most closely resembles these. case CSS::Repeat::Repeat: // The background rect is already sized to align with 'repeat'. break; - case CSS::Repeat::RepeatX: - background_rect.set_height(background_image.height()); - break; - case CSS::Repeat::RepeatY: + case CSS::Repeat::NoRepeat: background_rect.set_width(background_image.width()); break; + } + + switch (background_repeat_y) { + case CSS::Repeat::Round: + case CSS::Repeat::Space: + // FIXME: Support 'round' and 'space'. Fall through to 'repeat' since that most closely resembles these. + case CSS::Repeat::Repeat: + // The background rect is already sized to align with 'repeat'. + break; case CSS::Repeat::NoRepeat: - default: // FIXME: Support 'round' and 'square' - background_rect.set_width(background_image.width()); background_rect.set_height(background_image.height()); break; } diff --git a/Userland/Libraries/LibWeb/Layout/Box.h b/Userland/Libraries/LibWeb/Layout/Box.h index 7c6039c936..cd2813b666 100644 --- a/Userland/Libraries/LibWeb/Layout/Box.h +++ b/Userland/Libraries/LibWeb/Layout/Box.h @@ -153,7 +153,7 @@ protected: virtual void did_set_rect() { } - void paint_background_image(PaintContext&, const Gfx::Bitmap&, CSS::Repeat, Gfx::IntRect); + void paint_background_image(PaintContext&, const Gfx::Bitmap&, CSS::Repeat, CSS::Repeat, Gfx::IntRect); Vector<LineBox> m_line_boxes; diff --git a/Userland/Libraries/LibWeb/Layout/InitialContainingBlockBox.cpp b/Userland/Libraries/LibWeb/Layout/InitialContainingBlockBox.cpp index 16e03ab32f..df7663cc75 100644 --- a/Userland/Libraries/LibWeb/Layout/InitialContainingBlockBox.cpp +++ b/Userland/Libraries/LibWeb/Layout/InitialContainingBlockBox.cpp @@ -69,7 +69,7 @@ void InitialContainingBlockBox::paint_document_background(PaintContext& context) if (auto background_bitmap = document().background_image()) { Gfx::IntRect background_rect = { 0, 0, context.viewport_rect().x() + context.viewport_rect().width(), context.viewport_rect().y() + context.viewport_rect().height() }; - paint_background_image(context, *background_bitmap, document().background_repeat(), move(background_rect)); + paint_background_image(context, *background_bitmap, document().background_repeat_x(), document().background_repeat_y(), move(background_rect)); } } diff --git a/Userland/Libraries/LibWeb/Layout/Node.cpp b/Userland/Libraries/LibWeb/Layout/Node.cpp index 44989beba4..0706e23fe5 100644 --- a/Userland/Libraries/LibWeb/Layout/Node.cpp +++ b/Userland/Libraries/LibWeb/Layout/Node.cpp @@ -234,9 +234,13 @@ void NodeWithStyle::apply_style(const CSS::StyleProperties& specified_style) m_background_image = static_ptr_cast<CSS::ImageStyleValue>(bgimage.value()); } - auto background_repeat = specified_style.background_repeat(); - if (background_repeat.has_value()) - computed_values.set_background_repeat(background_repeat.value()); + auto background_repeat_x = specified_style.background_repeat_x(); + if (background_repeat_x.has_value()) + computed_values.set_background_repeat_x(background_repeat_x.value()); + + auto background_repeat_y = specified_style.background_repeat_y(); + if (background_repeat_y.has_value()) + computed_values.set_background_repeat_y(background_repeat_y.value()); computed_values.set_display(specified_style.display()); |