소스 검색

LibWeb: Apply "clip" property in `apply_clip_overflow_rect()`

Fixes bug when "clip" property does not affect abspos children.
This change makes "clip" property to be applied together with
"overflow: hidden" in `apply_clip_overflow_rect()` that already
handles abspos children correctly.
Aliaksandr Kalenik 1 년 전
부모
커밋
d06d4eb388

+ 11 - 0
Tests/LibWeb/Ref/clip-abspos-children-ref.html

@@ -0,0 +1,11 @@
+<!DOCTYPE html><style type="text/css">
+    * {
+        border: 1px solid black;
+    }
+    .outer {
+        position: absolute;
+    }
+    .inner {
+        position: absolute;
+    }
+</style><div class="outer"><div class="inner">

+ 17 - 0
Tests/LibWeb/Ref/clip-abspos-children.html

@@ -0,0 +1,17 @@
+<!DOCTYPE html><style type="text/css">
+    * {
+        border: 1px solid black;
+    }
+    .outer {
+        position: absolute;
+        clip: rect(0px, auto, auto, 0px);
+    }
+    .inner {
+        position: absolute;
+    }
+    svg {
+        width: 100px;
+        height: 100px;
+        fill: red;
+    }
+</style><div class="outer"><div class="inner"><svg viewBox="0 0 1 1"><rect x=0 y=0 width=1 height=1></rect><svg>

+ 1 - 0
Tests/LibWeb/Ref/manifest.json

@@ -1,4 +1,5 @@
 {
 {
+    "clip-abspos-children.html": "clip-abspos-children-ref.html",
     "item-with-negative-z-index.html": "item-with-negative-z-index-ref.html",
     "item-with-negative-z-index.html": "item-with-negative-z-index-ref.html",
     "img-srcset-viewport-relative-sizes.html": "img-srcset-viewport-relative-sizes-ref.html",
     "img-srcset-viewport-relative-sizes.html": "img-srcset-viewport-relative-sizes-ref.html",
     "grid-items-painting-order.html": "grid-items-painting-order-ref.html",
     "grid-items-painting-order.html": "grid-items-painting-order-ref.html",

+ 11 - 11
Userland/Libraries/LibWeb/Painting/PaintableBox.cpp

@@ -183,15 +183,7 @@ void PaintableBox::paint(PaintContext& context, PaintPhase phase) const
     if (!is_visible())
     if (!is_visible())
         return;
         return;
 
 
-    auto clip_rect = computed_values().clip();
-    auto should_clip_rect = clip_rect.is_rect() && layout_box().is_absolutely_positioned();
-
     if (phase == PaintPhase::Background) {
     if (phase == PaintPhase::Background) {
-        if (should_clip_rect) {
-            context.painter().save();
-            auto border_box = absolute_border_box_rect();
-            context.painter().add_clip_rect(context.rounded_device_rect(clip_rect.to_rect().resolved(Paintable::layout_node(), border_box.to_type<double>()).to_type<CSSPixels>()).to_type<int>());
-        }
         paint_backdrop_filter(context);
         paint_backdrop_filter(context);
         paint_background(context);
         paint_background(context);
         paint_box_shadow(context);
         paint_box_shadow(context);
@@ -229,9 +221,6 @@ void PaintableBox::paint(PaintContext& context, PaintPhase phase) const
         }
         }
     }
     }
 
 
-    if (phase == PaintPhase::Overlay && should_clip_rect)
-        context.painter().restore();
-
     if (phase == PaintPhase::Overlay && layout_box().document().inspected_layout_node() == &layout_box()) {
     if (phase == PaintPhase::Overlay && layout_box().document().inspected_layout_node() == &layout_box()) {
         auto content_rect = absolute_rect();
         auto content_rect = absolute_rect();
 
 
@@ -437,6 +426,17 @@ void PaintableBox::apply_clip_overflow_rect(PaintContext& context, PaintPhase ph
     auto overflow_x = computed_values().overflow_x();
     auto overflow_x = computed_values().overflow_x();
     auto overflow_y = computed_values().overflow_y();
     auto overflow_y = computed_values().overflow_y();
 
 
+    auto clip = computed_values().clip();
+    if (clip.is_rect() && layout_box().is_absolutely_positioned()) {
+        auto border_box = absolute_border_box_rect();
+        auto resolved_clip_rect = clip.to_rect().resolved(layout_node(), border_box.to_type<double>()).to_type<CSSPixels>();
+        if (clip_rect.has_value()) {
+            clip_rect->intersect(resolved_clip_rect);
+        } else {
+            clip_rect = resolved_clip_rect;
+        }
+    }
+
     if (!clip_rect.has_value())
     if (!clip_rect.has_value())
         return;
         return;