| OLD | NEW |
| (Empty) | |
| 1 <!DOCTYPE html> |
| 2 <div style="height: 200px; width: 100px;"></div> |
| 3 <div id="target" style="background-color: green; width:100px; height:100px"></di
v> |
| 4 <div style="height: 200px; width: 100px;"></div> |
| 5 |
| 6 <script> |
| 7 var port; |
| 8 var entries = []; |
| 9 var target = document.getElementById('target'); |
| 10 var scroller = document.scrollingElement; |
| 11 var nextStep; |
| 12 var waiting_for_ack = false; |
| 13 |
| 14 function clientRectToJson(rect) { |
| 15 if (!rect) |
| 16 return "null"; |
| 17 return { |
| 18 top: rect.top, |
| 19 right: rect.right, |
| 20 bottom: rect.bottom, |
| 21 left: rect.left |
| 22 }; |
| 23 } |
| 24 |
| 25 function entryToJson(entry) { |
| 26 return { |
| 27 boundingClientRect: clientRectToJson(entry.boundingClientRect), |
| 28 intersectionRect: clientRectToJson(entry.intersectionRect), |
| 29 rootBounds: clientRectToJson(entry.rootBounds), |
| 30 target: entry.target.id |
| 31 }; |
| 32 } |
| 33 |
| 34 function coordinatesToClientRectJson(top, right, bottom, left) { |
| 35 return { |
| 36 top: top, |
| 37 right: right, |
| 38 bottom: bottom, |
| 39 left: left |
| 40 }; |
| 41 } |
| 42 |
| 43 // Use a rootMargin here, and verify it does NOT get applied for the cross-origi
n case. |
| 44 var observer = new IntersectionObserver(function(changes) { |
| 45 entries = entries.concat(changes) |
| 46 }, { rootMargin: "7px" }); |
| 47 observer.observe(target); |
| 48 |
| 49 function step0() { |
| 50 entries = entries.concat(observer.takeRecords()); |
| 51 nextStep = step1; |
| 52 var expected = [{ |
| 53 boundingClientRect: coordinatesToClientRectJson(8, 208, 108, 308), |
| 54 intersectionRect: coordinatesToClientRectJson(0, 0, 0, 0), |
| 55 rootBounds: "null", |
| 56 target: target.id |
| 57 }]; |
| 58 port.postMessage({ |
| 59 actual: entries.map(entryToJson), |
| 60 expected: expected, |
| 61 description: "First rAF" |
| 62 }, "*"); |
| 63 entries = []; |
| 64 port.postMessage({scrollTo: 200}, "*"); |
| 65 } |
| 66 |
| 67 function step1() { |
| 68 entries = entries.concat(observer.takeRecords()); |
| 69 port.postMessage({ |
| 70 actual: entries.map(entryToJson), |
| 71 expected: [], |
| 72 description: "topDocument.scrollingElement.scrollTop = 200" |
| 73 }, "*"); |
| 74 entries = []; |
| 75 scroller.scrollTop = 250; |
| 76 nextStep = step2; |
| 77 port.postMessage({}, "*"); |
| 78 } |
| 79 |
| 80 function step2() { |
| 81 entries = entries.concat(observer.takeRecords()); |
| 82 var expected = [{ |
| 83 boundingClientRect: coordinatesToClientRectJson(-42, 108, 58, 8), |
| 84 intersectionRect: coordinatesToClientRectJson(0, 108, 58, 8), |
| 85 rootBounds: "null", |
| 86 target: target.id |
| 87 }]; |
| 88 port.postMessage({ |
| 89 actual: entries.map(entryToJson), |
| 90 expected: expected, |
| 91 description: "iframeDocument.scrollingElement.scrollTop = 250" |
| 92 }, "*"); |
| 93 entries = []; |
| 94 nextStep = step3; |
| 95 port.postMessage({scrollTo: 100}, "*"); |
| 96 } |
| 97 |
| 98 function step3() { |
| 99 entries = entries.concat(observer.takeRecords()); |
| 100 var expected = [{ |
| 101 boundingClientRect: coordinatesToClientRectJson(-42, 108, 58, 8), |
| 102 intersectionRect: coordinatesToClientRectJson(0, 0, 0, 0), |
| 103 rootBounds: "null", |
| 104 target: target.id |
| 105 }]; |
| 106 port.postMessage({ |
| 107 actual: entries.map(entryToJson), |
| 108 expected: expected, |
| 109 description: "topDocument.scrollingElement.scrollTop = 100" |
| 110 }, "*"); |
| 111 port.postMessage({DONE: 1}, "*"); |
| 112 } |
| 113 |
| 114 function handleMessage(event) |
| 115 { |
| 116 port = event.source; |
| 117 // The ACKs serve the purpose to create an extra full postMessage round trip |
| 118 // delay before taking IntersectionObserver records. This accounts for a |
| 119 // race condition that exists when this is an out-of-process iframe: the |
| 120 // postMessage can trigger takeRecords before new intersections have been |
| 121 // calculated. requestAnimationFrame() is not available here because of |
| 122 // frame throttling in the same-process scenario. |
| 123 if (event.data.hasOwnProperty('ACK')) { |
| 124 nextStep(); |
| 125 } else { |
| 126 port.postMessage({ ACK: 1 }, "*"); |
| 127 } |
| 128 } |
| 129 |
| 130 nextStep = step0; |
| 131 window.addEventListener("message", handleMessage); |
| 132 </script> |
| OLD | NEW |