summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Userland/Libraries/LibWeb/CSS/ComputedValues.h9
-rw-r--r--Userland/Libraries/LibWeb/CSS/Properties.json14
-rw-r--r--Userland/Libraries/LibWeb/CSS/StyleProperties.cpp28
-rw-r--r--Userland/Libraries/LibWeb/CSS/StyleProperties.h3
-rw-r--r--Userland/Libraries/LibWeb/CSS/StyleResolver.cpp71
-rw-r--r--Userland/Libraries/LibWeb/CSS/StyleValue.h2
-rw-r--r--Userland/Libraries/LibWeb/DOM/Document.cpp17
-rw-r--r--Userland/Libraries/LibWeb/DOM/Document.h3
-rw-r--r--Userland/Libraries/LibWeb/Layout/Box.cpp26
-rw-r--r--Userland/Libraries/LibWeb/Layout/Box.h2
-rw-r--r--Userland/Libraries/LibWeb/Layout/InitialContainingBlockBox.cpp2
-rw-r--r--Userland/Libraries/LibWeb/Layout/Node.cpp10
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());