Commit c317bae5 authored by Stefan Zager's avatar Stefan Zager Committed by Commit Bot

[IntersectionObserver] Fix handling of remote parent frame intersection

If a process-isolated iframe has a zero-area intersection with its
parent frame, implicit root observations should not be able to have
isIntersecting=true.

BUG=1070332
R=vmpstr@chromium.org

Change-Id: I05e8a05af14e84d493609bbc1675a28793dc1823
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2166605
Commit-Queue: vmpstr <vmpstr@chromium.org>
Reviewed-by: default avatarvmpstr <vmpstr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#762875}
parent e95c82b1
......@@ -473,11 +473,16 @@ bool IntersectionGeometry::ClipToRoot(const LayoutObject* root,
// done yet.
LocalFrame* local_root_frame = root->GetDocument().GetFrame();
IntRect clip_rect(local_root_frame->RemoteViewportIntersection());
// Map clip_rect from the coordinate system of the local root frame to
// the coordinate system of the remote main frame.
clip_rect.MoveBy(IntPoint(local_root_frame->RemoteViewportOffset()));
does_intersect &=
intersection_rect.InclusiveIntersect(PhysicalRect(clip_rect));
if (clip_rect.IsEmpty()) {
intersection_rect = PhysicalRect();
does_intersect = false;
} else {
// Map clip_rect from the coordinate system of the local root frame to
// the coordinate system of the remote main frame.
clip_rect.MoveBy(IntPoint(local_root_frame->RemoteViewportOffset()));
does_intersect &=
intersection_rect.InclusiveIntersect(PhysicalRect(clip_rect));
}
}
}
......
......@@ -29,10 +29,15 @@ function entryToJson(entry) {
intersectionRect: clientRectToJson(entry.intersectionRect),
rootBounds: clientRectToJson(entry.rootBounds),
isIntersecting: entry.isIntersecting,
target: entry.target.id
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.
......@@ -43,6 +48,7 @@ var observer = new IntersectionObserver(function(changes) {
}, { rootMargin: "7px" });
observer.observe(target);
observer.observe(emptyTarget);
observer.observe(document.documentElement);
function step0() {
entries = entries.concat(observer.takeRecords());
......@@ -59,6 +65,12 @@ function step0() {
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),
......@@ -71,9 +83,21 @@ function step0() {
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: expected,
description: "topDocument.scrollingElement.scrollTop = 200"
}, "*");
entries = [];
......@@ -121,6 +145,12 @@ function step3() {
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),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment