summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibWeb/Layout
diff options
context:
space:
mode:
authorTimothy Flynn <trflynn89@pm.me>2021-05-13 09:39:30 -0400
committerAndreas Kling <kling@serenityos.org>2021-05-13 16:16:25 +0200
commitdba261f79bf5b2973d39a2c76e34c84bcf5148af (patch)
tree13947823fc1229ea65e8cf80812ab2a4f031f21f /Userland/Libraries/LibWeb/Layout
parentd1ed6bce5dbdf48c9c335018343899e0aeed8255 (diff)
downloadserenity-dba261f79bf5b2973d39a2c76e34c84bcf5148af.zip
LibWeb: Propagate body background properties to root HTML element
The Acid1 test has a bit of an unusual background - the html and body tags have different background colors. Our painting order of the DOM was such that the body background was painted first, then all other elements were painted in-phase according to Appendix E of CSS 2.1. So the html element's background color was painted over the body background. This removes the special handling of the body background from InitialContainingBlockBox and now all boxes are painted in-phase. Doing this also exposed that we weren't handling Section 2.11.2 of the spec; when the html background is unset, the body's background should be propagated to the html element.
Diffstat (limited to 'Userland/Libraries/LibWeb/Layout')
-rw-r--r--Userland/Libraries/LibWeb/Layout/Box.cpp37
-rw-r--r--Userland/Libraries/LibWeb/Layout/InitialContainingBlockBox.cpp13
-rw-r--r--Userland/Libraries/LibWeb/Layout/InitialContainingBlockBox.h2
3 files changed, 32 insertions, 20 deletions
diff --git a/Userland/Libraries/LibWeb/Layout/Box.cpp b/Userland/Libraries/LibWeb/Layout/Box.cpp
index d3cd09e1fc..23b98e3604 100644
--- a/Userland/Libraries/LibWeb/Layout/Box.cpp
+++ b/Userland/Libraries/LibWeb/Layout/Box.cpp
@@ -7,6 +7,7 @@
#include <LibGfx/Painter.h>
#include <LibWeb/DOM/Document.h>
#include <LibWeb/HTML/HTMLBodyElement.h>
+#include <LibWeb/HTML/HTMLHtmlElement.h>
#include <LibWeb/Layout/BlockBox.h>
#include <LibWeb/Layout/Box.h>
#include <LibWeb/Page/Frame.h>
@@ -25,13 +26,37 @@ void Box::paint(PaintContext& context, PaintPhase phase)
auto padded_rect = this->padded_rect();
- if (phase == PaintPhase::Background && !is_body()) {
- auto background_rect = enclosing_int_rect(padded_rect);
- 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_x(), computed_values().background_repeat_y(), move(background_rect));
+ if (phase == PaintPhase::Background) {
+ // If the body's background properties were propagated to the root element, do no re-paint the body's background.
+ if (is_body() && document().html_element()->should_use_body_background_properties())
+ return;
+
+ Gfx::IntRect background_rect;
+
+ Color background_color = computed_values().background_color();
+ const Gfx::Bitmap* background_image = this->background_image() ? this->background_image()->bitmap() : nullptr;
+ CSS::Repeat background_repeat_x = computed_values().background_repeat_x();
+ CSS::Repeat background_repeat_y = computed_values().background_repeat_y();
+
+ if (is_root_element()) {
+ // CSS 2.1 Appendix E.2: If the element is a root element, paint the background over the entire canvas.
+ background_rect = context.viewport_rect();
+
+ // Section 2.11.2: If the computed value of background-image on the root element is none and its background-color is transparent,
+ // user agents must instead propagate the computed values of the background properties from that element’s first HTML BODY child element.
+ if (document().html_element()->should_use_body_background_properties()) {
+ background_color = document().background_color(context.palette());
+ background_image = document().background_image();
+ background_repeat_x = document().background_repeat_x();
+ background_repeat_y = document().background_repeat_y();
+ }
+ } else {
+ background_rect = enclosing_int_rect(padded_rect);
}
+
+ context.painter().fill_rect(background_rect, move(background_color));
+ if (background_image)
+ paint_background_image(context, *background_image, background_repeat_x, background_repeat_y, move(background_rect));
}
if (phase == PaintPhase::Border) {
diff --git a/Userland/Libraries/LibWeb/Layout/InitialContainingBlockBox.cpp b/Userland/Libraries/LibWeb/Layout/InitialContainingBlockBox.cpp
index 0b71a20cfa..3cd7f29a33 100644
--- a/Userland/Libraries/LibWeb/Layout/InitialContainingBlockBox.cpp
+++ b/Userland/Libraries/LibWeb/Layout/InitialContainingBlockBox.cpp
@@ -42,20 +42,9 @@ void InitialContainingBlockBox::build_stacking_context_tree()
});
}
-void InitialContainingBlockBox::paint_document_background(PaintContext& context)
-{
- context.painter().fill_rect(Gfx::IntRect { {}, context.viewport_rect().size() }, document().background_color(context.palette()));
- context.painter().translate(-context.viewport_rect().location());
-
- 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_x(), document().background_repeat_y(), move(background_rect));
- }
-}
-
void InitialContainingBlockBox::paint_all_phases(PaintContext& context)
{
- paint_document_background(context);
+ context.painter().translate(-context.viewport_rect().location());
stacking_context()->paint(context);
}
diff --git a/Userland/Libraries/LibWeb/Layout/InitialContainingBlockBox.h b/Userland/Libraries/LibWeb/Layout/InitialContainingBlockBox.h
index 1466b4bbc0..e32d283da4 100644
--- a/Userland/Libraries/LibWeb/Layout/InitialContainingBlockBox.h
+++ b/Userland/Libraries/LibWeb/Layout/InitialContainingBlockBox.h
@@ -20,8 +20,6 @@ public:
void paint_all_phases(PaintContext&);
- void paint_document_background(PaintContext&);
-
virtual HitTestResult hit_test(const Gfx::IntPoint&, HitTestType) const override;
const LayoutRange& selection() const { return m_selection; }