Ver Fonte

LibWeb: Do not include box's own scroll offset in get_client_rects()

Fixes https://github.com/SerenityOS/serenity/issues/23631
Aliaksandr Kalenik há 1 ano atrás
pai
commit
e232a84f0e

+ 2 - 0
Tests/LibWeb/Text/expected/IntersectionObserver/observe-box-inside-container-with-scrollable-overflow.txt

@@ -0,0 +1,2 @@
+  The box is not visible.
+The box is now visible.

+ 49 - 0
Tests/LibWeb/Text/input/IntersectionObserver/observe-box-inside-container-with-scrollable-overflow.html

@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<style>
+.scroll-box {
+    width: 300px;
+    height: 300px;
+    overflow: scroll;
+    border: 2px solid black;
+}
+
+.content-box {
+    width: 100%;
+    height: 600px;
+    position: relative;
+}
+
+.target-box {
+    width: 100px;
+    height: 100px;
+    background-color: red;
+    position: absolute;
+    top: 500px;
+}
+</style>
+<script src="../include.js"></script>
+<div class="scroll-box"><div class="content-box"><div class="target-box"></div></div></div>
+<script>
+    asyncTest(done => {
+        function onIntersection(entries) {
+            entries.forEach((entry) => {
+                if (entry.isIntersecting) {
+                    println("The box is now visible.");
+                    done();
+                } else {
+                    println("The box is not visible.");
+                }
+            });
+        }
+
+        let observer = new IntersectionObserver(onIntersection, {
+            root: document.querySelector(".scroll-box"),
+        });
+
+        observer.observe(document.querySelector(".target-box"));
+
+        setTimeout(() => {
+            document.querySelector(".scroll-box").scrollTop = 1000;
+        }, 100);
+    });
+</script>

+ 3 - 1
Userland/Libraries/LibWeb/DOM/Element.cpp

@@ -875,8 +875,10 @@ JS::NonnullGCPtr<Geometry::DOMRectList> Element::get_client_rects() const
     const_cast<Document&>(document()).update_paint_and_hit_testing_properties_if_needed();
 
     Gfx::AffineTransform transform;
+    if (auto const* paintable_box = this->paintable_box())
+        transform = Gfx::extract_2d_affine_transform(paintable_box->transform());
     CSSPixelPoint scroll_offset;
-    for (auto const* containing_block = this->paintable_box(); containing_block; containing_block = containing_block->containing_block()) {
+    for (auto const* containing_block = paintable()->containing_block(); containing_block; containing_block = containing_block->containing_block()) {
         transform = Gfx::extract_2d_affine_transform(containing_block->transform()).multiply(transform);
         scroll_offset.translate_by(containing_block->scroll_offset());
     }