| <!DOCTYPE html> |
| <script> |
| if (window.internals) |
| internals.settings.setViewportMetaEnabled(true); |
| </script> |
| <script src="../../../resources/testharness.js"></script> |
| <script src="../../../resources/testharnessreport.js"></script> |
| |
| <meta name="viewport" content="width=980"> |
| |
| <style> |
| html { |
| width: 100%; |
| height: 100%; |
| background-color: white; |
| } |
| body { |
| width: 100%; |
| height: 100%; |
| background-color: lightgrey; |
| margin: 0; |
| } |
| #widediv { |
| border: 5px solid black; |
| box-sizing: border-box; |
| width: 200%; |
| } |
| #target { |
| width: 300px; |
| height: 300px; |
| position: absolute; |
| top: 600%; |
| background-color: red; |
| margin-bottom: 600%; |
| } |
| p { |
| margin-top: 0; |
| } |
| </style> |
| <p> |
| This test verifies that intersection observer on the root is correct in the |
| presence of Android's quirky viewport mode when an element wider than the |
| initial contianing block is present. The light grey box represents the |
| initial contianing block. The wide black box ensures the page is zoomed out |
| further than the ICB. |
| </p> |
| |
| <p> |
| To test manually: Scroll down until you see the box. This test passes if, as |
| soon as the box intersects the viewport, it turns green. |
| </p> |
| <div id="widediv"></div> |
| <div id="target"></div> |
| |
| <script> |
| const box = document.getElementById("target"); |
| const targetTop = box.getBoundingClientRect().top; |
| const targetBottom = box.getBoundingClientRect().bottom; |
| |
| const viewportHeight = window.innerHeight; |
| const startIntersectingScrollTop = targetTop - viewportHeight; |
| const endIntersectingScrollTop = targetBottom; |
| |
| function isVisible() { |
| return window.scrollY >= startIntersectingScrollTop && |
| window.scrollY < targetBottom; |
| } |
| |
| function scrollToAndWaitFrame(y) { |
| return () => { |
| return new Promise((resolve) => { |
| window.scrollTo(0, y); |
| requestAnimationFrame(() => { |
| resolve(); |
| }); |
| }); |
| }; |
| } |
| |
| addEventListener("load", () => { |
| if (window.internals) |
| internals.setPageScaleFactor(0.5); |
| |
| promise_test( t => { |
| return new Promise((resolve, reject) => { |
| if (window.testRunner) |
| assert_equals(visualViewport.scale, 0.5, "Page must start zoomed out"); |
| |
| const callback = function(entries) { |
| if (window.testRunner) { |
| t.step(() => { |
| assert_equals(entries.length, 1, "Observing only one element"); |
| assert_equals(entries[0].isIntersecting, isVisible(), |
| "Report intersection only if element is on-screen"); |
| }); |
| } |
| box.style.backgroundColor = |
| entries[0].isIntersecting ? "green" : "red"; |
| }; |
| const observer = new IntersectionObserver(callback, {}); |
| observer.observe(box); |
| resolve(); |
| }) |
| .then(scrollToAndWaitFrame(startIntersectingScrollTop - 1)) |
| .then(scrollToAndWaitFrame(startIntersectingScrollTop + 1)) |
| .then(scrollToAndWaitFrame(endIntersectingScrollTop - 1)) |
| .then(scrollToAndWaitFrame(endIntersectingScrollTop + 1)); |
| }, "IntersectionObserver uses correct root box"); |
| }); |
| </script> |