| <!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> |