| <!DOCTYPE html> |
| <div style="height: 200px; width: 100px;"></div> |
| <div id="target" style="background-color: green; width:100px; height:100px"></div> |
| <div id="empty-target" style="width: 100px"></div> |
| <div style="height: 200px; width: 100px;"></div> |
| |
| <script> |
| var port; |
| var entries = []; |
| var target = document.getElementById("target"); |
| var emptyTarget = document.getElementById("empty-target"); |
| var scroller = document.scrollingElement; |
| var nextStep; |
| |
| function clientRectToJson(rect) { |
| if (!rect) |
| return "null"; |
| return { |
| top: rect.top, |
| right: rect.right, |
| bottom: rect.bottom, |
| left: rect.left |
| }; |
| } |
| |
| function entryToJson(entry) { |
| return { |
| boundingClientRect: clientRectToJson(entry.boundingClientRect), |
| intersectionRect: clientRectToJson(entry.intersectionRect), |
| rootBounds: clientRectToJson(entry.rootBounds), |
| isIntersecting: entry.isIntersecting, |
| target: entry.target.id |
| }; |
| } |
| |
| // Note that we never use RAF in this code, because this frame might get render-throttled. |
| // Instead of RAF-ing, we just post an empty message to the parent window, which will |
| // RAF when it is received, and then send us a message to cause the next step to run. |
| |
| // Use a rootMargin here, and verify it does NOT get applied for the cross-origin case. |
| var observer = new IntersectionObserver(function(changes) { |
| entries = entries.concat(changes) |
| }, { rootMargin: "7px" }); |
| observer.observe(target); |
| observer.observe(emptyTarget); |
| |
| function step0() { |
| entries = entries.concat(observer.takeRecords()); |
| nextStep = step1; |
| var expected = [{ |
| boundingClientRect: [8, 108, 208, 308], |
| intersectionRect: [0, 0, 0, 0], |
| rootBounds: "null", |
| isIntersecting: false, |
| target: target.id |
| }, { |
| boundingClientRect: [8, 108, 308, 308], |
| intersectionRect: [0, 0, 0, 0], |
| rootBounds: "null", |
| isIntersecting: false, |
| target: emptyTarget.id |
| }]; |
| port.postMessage({ |
| actual: entries.map(entryToJson), |
| expected: expected, |
| description: "First rAF" |
| }, "*"); |
| entries = []; |
| port.postMessage({scrollTo: 200}, "*"); |
| } |
| |
| function step1() { |
| entries = entries.concat(observer.takeRecords()); |
| port.postMessage({ |
| actual: entries.map(entryToJson), |
| expected: [], |
| description: "topDocument.scrollingElement.scrollTop = 200" |
| }, "*"); |
| entries = []; |
| scroller.scrollTop = 250; |
| nextStep = step2; |
| port.postMessage({}, "*"); |
| } |
| |
| function step2() { |
| entries = entries.concat(observer.takeRecords()); |
| var expected = [{ |
| boundingClientRect: [8, 108, -42, 58], |
| intersectionRect: [8, 108, 0, 58], |
| rootBounds: "null", |
| isIntersecting: true, |
| target: target.id |
| }, { |
| boundingClientRect: [8, 108, 58, 58], |
| intersectionRect: [8, 108, 58, 58], |
| rootBounds: "null", |
| isIntersecting: true, |
| target: emptyTarget.id |
| }]; |
| port.postMessage({ |
| actual: entries.map(entryToJson), |
| expected: expected, |
| description: "iframeDocument.scrollingElement.scrollTop = 250" |
| }, "*"); |
| entries = []; |
| nextStep = step3; |
| port.postMessage({scrollTo: 100}, "*"); |
| } |
| |
| function step3() { |
| entries = entries.concat(observer.takeRecords()); |
| var expected = [{ |
| boundingClientRect: [8, 108, -42, 58], |
| intersectionRect: [0, 0, 0, 0], |
| rootBounds: "null", |
| isIntersecting: false, |
| target: target.id |
| }, { |
| boundingClientRect: [8, 108, 58, 58], |
| intersectionRect: [0, 0, 0, 0], |
| rootBounds: "null", |
| isIntersecting: false, |
| target: emptyTarget.id |
| }]; |
| port.postMessage({ |
| actual: entries.map(entryToJson), |
| expected: expected, |
| description: "topDocument.scrollingElement.scrollTop = 100" |
| }, "*"); |
| port.postMessage({DONE: 1}, "*"); |
| } |
| |
| function handleMessage(event) |
| { |
| port = event.source; |
| nextStep(); |
| } |
| |
| nextStep = step0; |
| window.addEventListener("message", handleMessage); |
| </script> |