Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 55 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,31 @@ 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) {
var subviewportWidth =
iframeDoc.documentElement.clientWidth || iframeDoc.body.clientWidth;
var subviewportHeight =
iframeDoc.documentElement.clientHeight || iframeDoc.body.clientHeight;

expect(records.length).to.be(1);
expect(records[0].rootBounds.top).to.be(0);
Comment thread
samouri marked this conversation as resolved.
Outdated
expect(records[0].rootBounds.left).to.be(0);
expect(records[0].rootBounds.right).to.be(subviewportWidth);
expect(records[0].rootBounds.width).to.be(subviewportWidth);
expect(records[0].rootBounds.bottom).to.be(subviewportHeight);
expect(records[0].rootBounds.height).to.be(subviewportHeight);
done();
Comment thread
samouri marked this conversation as resolved.
},
{ root: iframeDoc }
);

io.observe(iframeTargetEl1);
});

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

Expand Down Expand Up @@ -3022,6 +3050,31 @@ 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) {
var subviewportWidth =
iframeDoc.documentElement.clientWidth || iframeDoc.body.clientWidth;
var subviewportHeight =
iframeDoc.documentElement.clientHeight || iframeDoc.body.clientHeight;

expect(records.length).to.be(1);
expect(records[0].rootBounds.top).to.be(0);
expect(records[0].rootBounds.left).to.be(0);
expect(records[0].rootBounds.right).to.be(subviewportWidth);
expect(records[0].rootBounds.width).to.be(subviewportWidth);
expect(records[0].rootBounds.bottom).to.be(subviewportHeight);
expect(records[0].rootBounds.height).to.be(subviewportHeight);
done();
Comment thread
samouri marked this conversation as resolved.
},
{ root: iframeDoc }
Comment thread
samouri marked this conversation as resolved.
);

io.observe(iframeTargetEl1);
});
});
});
});
Expand Down
32 changes: 24 additions & 8 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
Comment thread
samouri marked this conversation as resolved.
Outdated
) {
throw new Error("root must be a Document or Element");
Comment thread
samouri marked this conversation as resolved.
Outdated
}

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

// Also monitor the parent.
if (doc != (this.root && this.root.ownerDocument || document)) {
if (
doc != ((this.root && this.root.ownerDocument) || document) &&
!isDoc(this.root)
Comment thread
samouri marked this conversation as resolved.
Outdated
) {
var frame = getFrameElement(doc);
if (frame) {
this._monitorIntersections(frame.ownerDocument);
Expand All @@ -415,7 +422,9 @@ IntersectionObserver.prototype._unmonitorIntersections = function(doc) {
return;
}

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

// Check if any dependent targets are still remaining.
var hasDependentTargets =
Expand Down Expand Up @@ -618,7 +627,7 @@ IntersectionObserver.prototype._computeTargetAndRootIntersection =
*/
IntersectionObserver.prototype._getRootRect = function() {
var rootRect;
if (this.root) {
if (this.root && !isDoc(this.root)) {
Comment thread
samouri marked this conversation as resolved.
rootRect = getBoundingClientRect(this.root);
} else {
// Use <html>/<body> instead of window since scroll bars affect size.
Expand All @@ -630,7 +639,7 @@ IntersectionObserver.prototype._getRootRect = function() {
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
Copy Markdown
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 +723,11 @@ IntersectionObserver.prototype._rootIsInDom = function() {
* @private
*/
IntersectionObserver.prototype._rootContainsTarget = function(target) {
return containsDeep(this.root || document, target) &&
(!this.root || this.root.ownerDocument == target.ownerDocument);
const rootDoc = isDoc(this.root) ? this.root : this.root.ownerDocument;
return (
containsDeep(this.root || document, target) &&
Comment thread
samouri marked this conversation as resolved.
Outdated
(!this.root || rootDoc == target.ownerDocument)
);
};


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

function isDoc(node) {
Comment thread
samouri marked this conversation as resolved.
return node && node.nodeType === 9;
}


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