Stabilize and align Intersection Observers

- Fixes several crashes
- Aligns the feature with the W3C WD spec

Tag #249
This commit is contained in:
wolfbeast 2018-06-27 16:00:53 +02:00 committed by Roy Tam
commit 5af4107852
9 changed files with 111 additions and 64 deletions

View file

@ -325,7 +325,7 @@ limitations under the License.
});
it('does not trigger if target does not intersect when observing begins',
it('does trigger if target does not intersect when observing begins',
function(done) {
var spy = sinon.spy();
@ -334,7 +334,7 @@ limitations under the License.
targetEl2.style.top = '-40px';
io.observe(targetEl2);
callDelayed(function() {
expect(spy.callCount).to.be(0);
expect(spy.callCount).to.be(1);
done();
}, ASYNC_TIMEOUT);
});
@ -528,7 +528,7 @@ limitations under the License.
spy.waitForNotification(function() {
expect(spy.callCount).to.be(1);
var records = sortRecords(spy.lastCall.args[0]);
expect(records.length).to.be(2);
expect(records.length).to.be(3);
expect(records[0].target).to.be(targetEl1);
expect(records[0].intersectionRatio).to.be(0.25);
expect(records[1].target).to.be(targetEl2);
@ -636,10 +636,10 @@ limitations under the License.
expect(records.length).to.be(3);
expect(records[0].target).to.be(targetEl1);
expect(records[0].intersectionRatio).to.be(0.5);
expect(records[1].target).to.be(targetEl3);
expect(records[1].intersectionRatio).to.be(0.5);
expect(records[2].target).to.be(targetEl4);
expect(records[2].target).to.be(targetEl3);
expect(records[2].intersectionRatio).to.be(0.5);
expect(records[3].target).to.be(targetEl4);
expect(records[3].intersectionRatio).to.be(0.5);
io.disconnect();
done();
}, {root: rootEl, rootMargin: '-10px 10%'});
@ -652,11 +652,11 @@ limitations under the License.
function(done) {
io = new IntersectionObserver(function(records) {
records = sortRecords(records);
expect(records.length).to.be(2);
expect(records.length).to.be(4);
expect(records[0].target).to.be(targetEl1);
expect(records[0].intersectionRatio).to.be(0.5);
expect(records[1].target).to.be(targetEl4);
expect(records[1].intersectionRatio).to.be(0.5);
expect(records[3].target).to.be(targetEl4);
expect(records[3].intersectionRatio).to.be(0.5);
io.disconnect();
done();
}, {root: rootEl, rootMargin: '-5% -2.5% 0px'});
@ -669,13 +669,13 @@ limitations under the License.
function(done) {
io = new IntersectionObserver(function(records) {
records = sortRecords(records);
expect(records.length).to.be(3);
expect(records.length).to.be(4);
expect(records[0].target).to.be(targetEl1);
expect(records[0].intersectionRatio).to.be(0.5);
expect(records[1].target).to.be(targetEl2);
expect(records[1].intersectionRatio).to.be(0.5);
expect(records[2].target).to.be(targetEl4);
expect(records[2].intersectionRatio).to.be(0.25);
expect(records[3].target).to.be(targetEl4);
expect(records[3].intersectionRatio).to.be(0.25);
io.disconnect();
done();
}, {root: rootEl, rootMargin: '5% -2.5% -10px -190px'});
@ -705,9 +705,9 @@ limitations under the License.
spy.waitForNotification(function() {
expect(spy.callCount).to.be(1);
var records = sortRecords(spy.lastCall.args[0]);
expect(records.length).to.be(1);
expect(records[0].intersectionRatio).to.be(0);
expect(records[0].target).to.be(targetEl2);
expect(records.length).to.be(2);
expect(records[1].intersectionRatio).to.be(0);
expect(records[1].target).to.be(targetEl2);
done();
}, ASYNC_TIMEOUT);
},
@ -797,14 +797,14 @@ limitations under the License.
function(done) {
document.getElementById('fixtures').appendChild(rootEl);
callDelayed(function() {
expect(spy.callCount).to.be(0);
expect(spy.callCount).to.be(1);
done();
}, ASYNC_TIMEOUT);
},
function(done) {
parentEl.insertBefore(targetEl1, targetEl2);
spy.waitForNotification(function() {
expect(spy.callCount).to.be(1);
expect(spy.callCount).to.be(2);
var records = sortRecords(spy.lastCall.args[0]);
expect(records.length).to.be(1);
expect(records[0].intersectionRatio).to.be(1);
@ -815,7 +815,7 @@ limitations under the License.
function(done) {
grandParentEl.parentNode.removeChild(grandParentEl);
spy.waitForNotification(function() {
expect(spy.callCount).to.be(2);
expect(spy.callCount).to.be(3);
var records = sortRecords(spy.lastCall.args[0]);
expect(records.length).to.be(1);
expect(records[0].intersectionRatio).to.be(0);
@ -826,7 +826,7 @@ limitations under the License.
function(done) {
rootEl.appendChild(targetEl1);
spy.waitForNotification(function() {
expect(spy.callCount).to.be(3);
expect(spy.callCount).to.be(4);
var records = sortRecords(spy.lastCall.args[0]);
expect(records.length).to.be(1);
expect(records[0].intersectionRatio).to.be(1);
@ -837,7 +837,7 @@ limitations under the License.
function(done) {
rootEl.parentNode.removeChild(rootEl);
spy.waitForNotification(function() {
expect(spy.callCount).to.be(4);
expect(spy.callCount).to.be(5);
var records = sortRecords(spy.lastCall.args[0]);
expect(records.length).to.be(1);
expect(records[0].intersectionRatio).to.be(0);
@ -867,8 +867,14 @@ limitations under the License.
targetEl1.style.top = '220px';
targetEl1.style.left = '220px';
var callCount = 0;
io = new IntersectionObserver(function(records) {
callCount++;
if (callCount <= 1) {
return;
}
expect(records.length).to.be(1);
expect(records[0].intersectionRatio).to.be(1);
done();
@ -891,6 +897,19 @@ limitations under the License.
var win = window.open("intersectionobserver_window.html");
});
it('triggers only once if observed multiple times (and does not crash when collected)', function(done) {
var spy = sinon.spy();
io = new IntersectionObserver(spy, {root: rootEl});
io.observe(targetEl1);
io.observe(targetEl1);
io.observe(targetEl1);
callDelayed(function () {
expect(spy.callCount).to.be(1);
done();
}, ASYNC_TIMEOUT);
});
});
describe('observe subframe', function () {