171 lines
4.8 KiB
HTML
171 lines
4.8 KiB
HTML
<!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 === document.documentElement ? "html" : entry.target.id
|
|
};
|
|
}
|
|
|
|
function boundingClientRectToJson(element) {
|
|
let r = element.getBoundingClientRect();
|
|
return [r.left, r.right, r.top, r.bottom];
|
|
}
|
|
|
|
// 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);
|
|
observer.observe(document.documentElement);
|
|
|
|
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
|
|
}, {
|
|
boundingClientRect: boundingClientRectToJson(document.documentElement),
|
|
intersectionRect: [0, 0, 0, 0],
|
|
rootBounds: "null",
|
|
isIntersecting: false,
|
|
target: "html"
|
|
}];
|
|
port.postMessage({
|
|
actual: entries.map(entryToJson),
|
|
expected: expected,
|
|
description: "First rAF"
|
|
}, "*");
|
|
entries = [];
|
|
port.postMessage({scrollTo: 200}, "*");
|
|
}
|
|
|
|
function step1() {
|
|
entries = entries.concat(observer.takeRecords());
|
|
var client_rect = boundingClientRectToJson(document.documentElement);
|
|
// When the top document is scrolled all the way up, the iframe element is
|
|
// 108px below the scrolling viewport, and the iframe has a 2px border. When
|
|
// the top document is scrolled to y=200, the top 90px of the iframe's content
|
|
// is visible.
|
|
var expected = [{
|
|
boundingClientRect: client_rect,
|
|
intersectionRect: client_rect.slice(0, 3).concat(90),
|
|
rootBounds: "null",
|
|
isIntersecting: true,
|
|
target: "html"
|
|
}];
|
|
port.postMessage({
|
|
actual: entries.map(entryToJson),
|
|
expected: 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
|
|
}, {
|
|
boundingClientRect: boundingClientRectToJson(document.documentElement),
|
|
intersectionRect: [0, 0, 0, 0],
|
|
rootBounds: "null",
|
|
isIntersecting: false,
|
|
target: "html"
|
|
}];
|
|
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>
|