Commit 39fcf43a authored by szager's avatar szager Committed by Commit bot

IntersectionObserver: send notifications when objects disappear.

TEST=intersection-observer/display-none.html
BUG=621693
R=eae@chromium.org

Review-Url: https://codereview.chromium.org/2149033003
Cr-Commit-Position: refs/heads/master@{#405630}
parent 8983ba5e
Test that setting display:none will send a not-intersecting notification.
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
PASS entries.length is 0
PASS entries.length is 0
PASS entries.length is 0
PASS entries.length is 1
PASS entries[0].boundingClientRect.left is 11
PASS entries[0].boundingClientRect.right is 111
PASS entries[0].boundingClientRect.top is 261
PASS entries[0].boundingClientRect.bottom is 361
PASS entries[0].intersectionRect.left is 11
PASS entries[0].intersectionRect.right is 111
PASS entries[0].intersectionRect.top is 261
PASS entries[0].intersectionRect.bottom is 311
PASS entries[0].rootBounds.left is 11
PASS entries[0].rootBounds.right is 111
PASS entries[0].rootBounds.top is 111
PASS entries[0].rootBounds.bottom is 311
PASS entries[0].target is [object HTMLDivElement]
PASS entries.length is 2
PASS entries[1].boundingClientRect.left is 0
PASS entries[1].boundingClientRect.right is 0
PASS entries[1].boundingClientRect.top is 0
PASS entries[1].boundingClientRect.bottom is 0
PASS entries[1].intersectionRect.left is 0
PASS entries[1].intersectionRect.right is 0
PASS entries[1].intersectionRect.top is 0
PASS entries[1].intersectionRect.bottom is 0
PASS entries[1].rootBounds.left is 0
PASS entries[1].rootBounds.right is 0
PASS entries[1].rootBounds.top is 0
PASS entries[1].rootBounds.bottom is 0
PASS entries[1].target is [object HTMLDivElement]
PASS entries.length is 3
PASS entries[2].boundingClientRect.left is 11
PASS entries[2].boundingClientRect.right is 111
PASS entries[2].boundingClientRect.top is 261
PASS entries[2].boundingClientRect.bottom is 361
PASS entries[2].intersectionRect.left is 11
PASS entries[2].intersectionRect.right is 111
PASS entries[2].intersectionRect.top is 261
PASS entries[2].intersectionRect.bottom is 311
PASS entries[2].rootBounds.left is 11
PASS entries[2].rootBounds.right is 111
PASS entries[2].rootBounds.top is 111
PASS entries[2].rootBounds.bottom is 311
PASS entries[2].target is [object HTMLDivElement]
PASS successfullyParsed is true
TEST COMPLETE
<!DOCTYPE html>
<script src="../resources/js-test.js"></script>
<script src="../resources/intersection-observer-helper-functions.js"></script>
<style>
#root {
display: inline-block;
overflow-y: scroll;
height: 200px;
border: 3px solid black;
}
#target {
background-color: green;
width: 100px;
height: 100px;
}
</style>
<div style="width:100%; height:700px;"></div>
<div id="root">
<div style="width:100px; height: 300px;"></div>
<div id="target"></div>
<div style="width:100%;height:700px;"></div>
</div>
<div style="width:100%;height:700px;"></div>
<script>
description("Test that setting display:none will send a not-intersecting notification.");
var target = document.getElementById("target");
var root = document.getElementById("root");
var entries = [];
var observer = new IntersectionObserver(
changes => { entries = entries.concat(changes) },
{ root: document.getElementById("root") }
);
onload = function() {
observer.observe(target);
entries = entries.concat(observer.takeRecords());
shouldBeEqualToNumber("entries.length", 0);
waitForNotification(step0);
}
function step0() {
shouldBeEqualToNumber("entries.length", 0);
document.scrollingElement.scrollTop = 600;
waitForNotification(step1);
}
function step1() {
shouldBeEqualToNumber("entries.length", 0);
root.scrollTop = 150;
waitForNotification(step2);
}
function step2() {
shouldBeEqualToNumber("entries.length", 1);
if (entries.length > 0) {
shouldBeEqualToNumber("entries[0].boundingClientRect.left", 11);
shouldBeEqualToNumber("entries[0].boundingClientRect.right", 111);
shouldBeEqualToNumber("entries[0].boundingClientRect.top", 261);
shouldBeEqualToNumber("entries[0].boundingClientRect.bottom", 361);
shouldBeEqualToNumber("entries[0].intersectionRect.left", 11);
shouldBeEqualToNumber("entries[0].intersectionRect.right", 111);
shouldBeEqualToNumber("entries[0].intersectionRect.top", 261);
shouldBeEqualToNumber("entries[0].intersectionRect.bottom", 311);
shouldBeEqualToNumber("entries[0].rootBounds.left", 11);
shouldBeEqualToNumber("entries[0].rootBounds.right", 111);
shouldBeEqualToNumber("entries[0].rootBounds.top", 111);
shouldBeEqualToNumber("entries[0].rootBounds.bottom", 311);
shouldEvaluateToSameObject("entries[0].target", target);
}
target.style.display = "none";
waitForNotification(step3);
}
function step3() {
shouldBeEqualToNumber("entries.length", 2);
if (entries.length > 1) {
shouldBeEqualToNumber("entries[1].boundingClientRect.left", 0);
shouldBeEqualToNumber("entries[1].boundingClientRect.right", 0);
shouldBeEqualToNumber("entries[1].boundingClientRect.top", 0);
shouldBeEqualToNumber("entries[1].boundingClientRect.bottom", 0);
shouldBeEqualToNumber("entries[1].intersectionRect.left", 0);
shouldBeEqualToNumber("entries[1].intersectionRect.right", 0);
shouldBeEqualToNumber("entries[1].intersectionRect.top", 0);
shouldBeEqualToNumber("entries[1].intersectionRect.bottom", 0);
shouldBeEqualToNumber("entries[1].rootBounds.left", 0);
shouldBeEqualToNumber("entries[1].rootBounds.right", 0);
shouldBeEqualToNumber("entries[1].rootBounds.top", 0);
shouldBeEqualToNumber("entries[1].rootBounds.bottom", 0);
shouldEvaluateToSameObject("entries[1].target", target);
}
target.style.display = "";
waitForNotification(step4);
}
function step4() {
shouldBeEqualToNumber("entries.length", 3);
if (entries.length > 2) {
shouldBeEqualToNumber("entries[2].boundingClientRect.left", 11);
shouldBeEqualToNumber("entries[2].boundingClientRect.right", 111);
shouldBeEqualToNumber("entries[2].boundingClientRect.top", 261);
shouldBeEqualToNumber("entries[2].boundingClientRect.bottom", 361);
shouldBeEqualToNumber("entries[2].intersectionRect.left", 11);
shouldBeEqualToNumber("entries[2].intersectionRect.right", 111);
shouldBeEqualToNumber("entries[2].intersectionRect.top", 261);
shouldBeEqualToNumber("entries[2].intersectionRect.bottom", 311);
shouldBeEqualToNumber("entries[2].rootBounds.left", 11);
shouldBeEqualToNumber("entries[2].rootBounds.right", 111);
shouldBeEqualToNumber("entries[2].rootBounds.top", 111);
shouldBeEqualToNumber("entries[2].rootBounds.bottom", 311);
shouldEvaluateToSameObject("entries[2].target", target);
}
finishJSTest();
}
</script>
......@@ -143,7 +143,8 @@ bool IntersectionObservation::computeGeometry(IntersectionGeometry& geometry) co
// effectively means "if the previous observed state was that root and target were
// intersecting, then generate a notification indicating that they are no longer
// intersecting." This happens, for example, when root or target is removed from the
// DOM tree and not reinserted before the next frame is generated.
// DOM tree and not reinserted before the next frame is generated, or display:none
// is set on the root or target.
Element* targetElement = target();
if (!targetElement)
return false;
......@@ -156,13 +157,13 @@ bool IntersectionObservation::computeGeometry(IntersectionGeometry& geometry) co
LayoutObject* rootLayoutObject = m_observer->rootLayoutObject();
if (!rootLayoutObject || !rootLayoutObject->isBoxModelObject())
return false;
return true;
// TODO(szager): Support SVG
LayoutObject* targetLayoutObject = targetElement->layoutObject();
if (!targetLayoutObject)
return false;
return true;
if (!targetLayoutObject->isBoxModelObject() && !targetLayoutObject->isText())
return false;
return true;
if (!isContainingBlockChainDescendant(targetLayoutObject, rootLayoutObject))
return true;
......
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