Skip to content
37 changes: 35 additions & 2 deletions polyfill/intersection-observer-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,15 @@ describe('IntersectionObserver', function() {
io = new IntersectionObserver(noop);
expect(io.root).to.be(null);

io = new IntersectionObserver(noop, {root: document});
expect(io.root).to.be(document);

io = new IntersectionObserver(noop, {root: rootEl});
expect(io.root).to.be(rootEl);
expect(io.root).to.be(rootEl);
});


it('throws when root is not an Element', function() {
it('throws when root is not a Document or Element', function() {
expect(function() {
io = new IntersectionObserver(noop, {root: 'foo'});
}).to.throwException();
Expand Down Expand Up @@ -1398,6 +1401,21 @@ describe('IntersectionObserver', function() {
io.observe(iframeTargetEl2);
});

it('handles tracking iframe viewport', function(done) {
iframe.style.height = '100px';
// {root:iframeDoc} means to track the iframe viewport irrespective of toplevel viewport
var io = new IntersectionObserver(
function (records) {
expect(records.length).to.be(1);
expect(rect(records[0].rootBounds)).to.eql(getRootRect(iframeDoc));
done();
},
{ root: iframeDoc }
);

io.observe(iframeTargetEl1);
});

it('handles style changes', function(done) {
var spy = sinon.spy();

Expand Down Expand Up @@ -3022,6 +3040,21 @@ describe('IntersectionObserver', function() {
}
], done);
});

it('handles tracking iframe viewport', function(done) {
iframe.style.height = '100px';
// {root:iframeDoc} means to track the iframe viewport irrespective of toplevel viewport
var io = new IntersectionObserver(
function (records) {
expect(records.length).to.be(1);
expect(rect(records[0].rootBounds)).to.eql(getRootRect(iframeDoc));
done();
},
{ root: iframeDoc }
);

io.observe(iframeTargetEl1);
});
});
});
});
Expand Down
36 changes: 26 additions & 10 deletions polyfill/intersection-observer.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,12 @@ function IntersectionObserver(callback, opt_options) {
throw new Error('callback must be a function');
}

if (options.root && options.root.nodeType != 1) {
throw new Error('root must be an Element');
if (
options.root &&
options.root.nodeType != 1 &&
options.root.nodeType != 9
) {
throw new Error('root must be a Document or Element');
}

// Binds and throttles `this._checkForIntersections`.
Expand Down Expand Up @@ -395,7 +399,9 @@ IntersectionObserver.prototype._monitorIntersections = function(doc) {
});

// Also monitor the parent.
if (doc != (this.root && this.root.ownerDocument || document)) {
var rootDoc =
(this.root && (this.root.ownerDocument || this.root)) || document;
if (doc != rootDoc) {
var frame = getFrameElement(doc);
if (frame) {
this._monitorIntersections(frame.ownerDocument);
Expand All @@ -415,7 +421,8 @@ IntersectionObserver.prototype._unmonitorIntersections = function(doc) {
return;
}

var rootDoc = (this.root && this.root.ownerDocument || document);
var rootDoc =
(this.root && (this.root.ownerDocument || this.root)) || document;

// Check if any dependent targets are still remaining.
var hasDependentTargets =
Expand Down Expand Up @@ -618,19 +625,20 @@ IntersectionObserver.prototype._computeTargetAndRootIntersection =
*/
IntersectionObserver.prototype._getRootRect = function() {
var rootRect;
if (this.root) {
if (this.root && !isDoc(this.root)) {
rootRect = getBoundingClientRect(this.root);
} else {
// Use <html>/<body> instead of window since scroll bars affect size.
var html = document.documentElement;
var body = document.body;
var doc = isDoc(this.root) ? this.root : document;
var html = doc.documentElement;
var body = doc.body;
rootRect = {
top: 0,
left: 0,
right: html.clientWidth || body.clientWidth,
width: html.clientWidth || body.clientWidth,
bottom: html.clientHeight || body.clientHeight,
height: html.clientHeight || body.clientHeight
height: html.clientHeight || body.clientHeight,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't do this in IE :( No trailing commas. You might have to disable the prettier.

};
}
return this._expandRectByRootMargin(rootRect);
Expand Down Expand Up @@ -714,8 +722,12 @@ IntersectionObserver.prototype._rootIsInDom = function() {
* @private
*/
IntersectionObserver.prototype._rootContainsTarget = function(target) {
return containsDeep(this.root || document, target) &&
(!this.root || this.root.ownerDocument == target.ownerDocument);
var rootDoc =
(this.root && (this.root.ownerDocument || this.root)) || document;
return (
containsDeep(this.root || rootDoc, target) &&
(!this.root || rootDoc == target.ownerDocument)
);
};


Expand Down Expand Up @@ -978,6 +990,10 @@ function getParentNode(node) {
return parent;
}

function isDoc(node) {
return node && node.nodeType === 9;
}


// Exposes the constructors globally.
window.IntersectionObserver = IntersectionObserver;
Expand Down