intersection-observer 0.9.0 → 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
- package/intersection-observer-test.js +17 -0
- package/intersection-observer.js +47 -18
- package/package.json +1 -1
@@ -157,6 +157,21 @@ describe('IntersectionObserver', function() {
|
|
157
157
|
}).to.throwException();
|
158
158
|
});
|
159
159
|
|
160
|
+
it('fills in x and y in the resulting rects', function(done) {
|
161
|
+
io = new IntersectionObserver(function(records) {
|
162
|
+
expect(records.length).to.be(1);
|
163
|
+
var entry = records[0];
|
164
|
+
expect(entry.rootBounds.x).to.be(entry.rootBounds.left);
|
165
|
+
expect(entry.rootBounds.y).to.be(entry.rootBounds.top);
|
166
|
+
expect(entry.boundingClientRect.x).to.be(entry.boundingClientRect.left);
|
167
|
+
expect(entry.boundingClientRect.y).to.be(entry.boundingClientRect.top);
|
168
|
+
expect(entry.intersectionRect.x).to.be(entry.intersectionRect.left);
|
169
|
+
expect(entry.intersectionRect.y).to.be(entry.intersectionRect.top);
|
170
|
+
done();
|
171
|
+
}, {root: rootEl});
|
172
|
+
targetEl2.style.top = '-40px';
|
173
|
+
io.observe(targetEl1);
|
174
|
+
});
|
160
175
|
|
161
176
|
it('triggers for all targets when observing begins', function(done) {
|
162
177
|
io = new IntersectionObserver(function(records) {
|
@@ -1000,6 +1015,8 @@ describe('IntersectionObserver', function() {
|
|
1000
1015
|
|
1001
1016
|
function rect(r) {
|
1002
1017
|
return {
|
1018
|
+
y: typeof r.y == 'number' ? r.y : r.top,
|
1019
|
+
x: typeof r.x == 'number' ? r.x : r.left,
|
1003
1020
|
top: r.top,
|
1004
1021
|
left: r.left,
|
1005
1022
|
width: r.width != null ? r.width : r.right - r.left,
|
package/intersection-observer.js
CHANGED
@@ -51,13 +51,13 @@ var registry = [];
|
|
51
51
|
/**
|
52
52
|
* The signal updater for cross-origin intersection. When not null, it means
|
53
53
|
* that the polyfill is configured to work in a cross-origin mode.
|
54
|
-
* @type {function(DOMRect, DOMRect)}
|
54
|
+
* @type {function(DOMRect|ClientRect, DOMRect|ClientRect)}
|
55
55
|
*/
|
56
56
|
var crossOriginUpdater = null;
|
57
57
|
|
58
58
|
/**
|
59
59
|
* The current cross-origin intersection. Only used in the cross-origin mode.
|
60
|
-
* @type {DOMRect}
|
60
|
+
* @type {DOMRect|ClientRect}
|
61
61
|
*/
|
62
62
|
var crossOriginRect = null;
|
63
63
|
|
@@ -71,9 +71,9 @@ var crossOriginRect = null;
|
|
71
71
|
function IntersectionObserverEntry(entry) {
|
72
72
|
this.time = entry.time;
|
73
73
|
this.target = entry.target;
|
74
|
-
this.rootBounds = entry.rootBounds;
|
75
|
-
this.boundingClientRect = entry.boundingClientRect;
|
76
|
-
this.intersectionRect = entry.intersectionRect || getEmptyRect();
|
74
|
+
this.rootBounds = ensureDOMRect(entry.rootBounds);
|
75
|
+
this.boundingClientRect = ensureDOMRect(entry.boundingClientRect);
|
76
|
+
this.intersectionRect = ensureDOMRect(entry.intersectionRect || getEmptyRect());
|
77
77
|
this.isIntersecting = !!entry.intersectionRect;
|
78
78
|
|
79
79
|
// Calculates the intersection ratio.
|
@@ -167,13 +167,13 @@ IntersectionObserver.prototype.USE_MUTATION_OBSERVER = true;
|
|
167
167
|
* parent via `IntersectionObserverEntry`. This function should be called
|
168
168
|
* each time the iframe receives intersection information from the parent
|
169
169
|
* window, e.g. via messaging.
|
170
|
-
* @return {function(DOMRect, DOMRect)}
|
170
|
+
* @return {function(DOMRect|ClientRect, DOMRect|ClientRect)}
|
171
171
|
*/
|
172
172
|
IntersectionObserver._setupCrossOriginUpdater = function() {
|
173
173
|
if (!crossOriginUpdater) {
|
174
174
|
/**
|
175
|
-
* @param {DOMRect} boundingClientRect
|
176
|
-
* @param {DOMRect} intersectionRect
|
175
|
+
* @param {DOMRect|ClientRect} boundingClientRect
|
176
|
+
* @param {DOMRect|ClientRect} intersectionRect
|
177
177
|
*/
|
178
178
|
crossOriginUpdater = function(boundingClientRect, intersectionRect) {
|
179
179
|
if (!boundingClientRect || !intersectionRect) {
|
@@ -593,7 +593,7 @@ IntersectionObserver.prototype._computeTargetAndRootIntersection =
|
|
593
593
|
|
594
594
|
/**
|
595
595
|
* Returns the root rect after being expanded by the rootMargin value.
|
596
|
-
* @return {
|
596
|
+
* @return {ClientRect} The expanded root rect.
|
597
597
|
* @private
|
598
598
|
*/
|
599
599
|
IntersectionObserver.prototype._getRootRect = function() {
|
@@ -619,8 +619,8 @@ IntersectionObserver.prototype._getRootRect = function() {
|
|
619
619
|
|
620
620
|
/**
|
621
621
|
* Accepts a rect and expands it by the rootMargin value.
|
622
|
-
* @param {
|
623
|
-
* @return {
|
622
|
+
* @param {DOMRect|ClientRect} rect The rect object to expand.
|
623
|
+
* @return {ClientRect} The expanded rect.
|
624
624
|
* @private
|
625
625
|
*/
|
626
626
|
IntersectionObserver.prototype._expandRectByRootMargin = function(rect) {
|
@@ -792,8 +792,8 @@ function removeEvent(node, event, fn, opt_useCapture) {
|
|
792
792
|
* Returns the intersection between two rect objects.
|
793
793
|
* @param {Object} rect1 The first rect.
|
794
794
|
* @param {Object} rect2 The second rect.
|
795
|
-
* @return {?Object} The intersection rect or undefined if no
|
796
|
-
* is found.
|
795
|
+
* @return {?Object|?ClientRect} The intersection rect or undefined if no
|
796
|
+
* intersection is found.
|
797
797
|
*/
|
798
798
|
function computeRectIntersection(rect1, rect2) {
|
799
799
|
var top = Math.max(rect1.top, rect2.top);
|
@@ -817,7 +817,7 @@ function computeRectIntersection(rect1, rect2) {
|
|
817
817
|
/**
|
818
818
|
* Shims the native getBoundingClientRect for compatibility with older IE.
|
819
819
|
* @param {Element} el The element whose bounding rect to get.
|
820
|
-
* @return {
|
820
|
+
* @return {DOMRect|ClientRect} The (possibly shimmed) rect of the element.
|
821
821
|
*/
|
822
822
|
function getBoundingClientRect(el) {
|
823
823
|
var rect;
|
@@ -849,7 +849,7 @@ function getBoundingClientRect(el) {
|
|
849
849
|
/**
|
850
850
|
* Returns an empty rect object. An empty rect is returned when an element
|
851
851
|
* is not in the DOM.
|
852
|
-
* @return {
|
852
|
+
* @return {ClientRect} The empty rect.
|
853
853
|
*/
|
854
854
|
function getEmptyRect() {
|
855
855
|
return {
|
@@ -863,12 +863,41 @@ function getEmptyRect() {
|
|
863
863
|
}
|
864
864
|
|
865
865
|
|
866
|
+
/**
|
867
|
+
* Ensure that the result has all of the necessary fields of the DOMRect.
|
868
|
+
* Specifically this ensures that `x` and `y` fields are set.
|
869
|
+
*
|
870
|
+
* @param {?DOMRect|?ClientRect} rect
|
871
|
+
* @return {?DOMRect}
|
872
|
+
*/
|
873
|
+
function ensureDOMRect(rect) {
|
874
|
+
// A `DOMRect` object has `x` and `y` fields.
|
875
|
+
if (!rect || 'x' in rect) {
|
876
|
+
return rect;
|
877
|
+
}
|
878
|
+
// A IE's `ClientRect` type does not have `x` and `y`. The same is the case
|
879
|
+
// for internally calculated Rect objects. For the purposes of
|
880
|
+
// `IntersectionObserver`, it's sufficient to simply mirror `left` and `top`
|
881
|
+
// for these fields.
|
882
|
+
return {
|
883
|
+
top: rect.top,
|
884
|
+
y: rect.top,
|
885
|
+
bottom: rect.bottom,
|
886
|
+
left: rect.left,
|
887
|
+
x: rect.left,
|
888
|
+
right: rect.right,
|
889
|
+
width: rect.width,
|
890
|
+
height: rect.height
|
891
|
+
};
|
892
|
+
}
|
893
|
+
|
894
|
+
|
866
895
|
/**
|
867
896
|
* Inverts the intersection and bounding rect from the parent (frame) BCR to
|
868
897
|
* the local BCR space.
|
869
|
-
* @param {
|
870
|
-
* @param {
|
871
|
-
* @return {
|
898
|
+
* @param {DOMRect|ClientRect} parentBoundingRect The parent's bound client rect.
|
899
|
+
* @param {DOMRect|ClientRect} parentIntersectionRect The parent's own intersection rect.
|
900
|
+
* @return {ClientRect} The local root bounding rect for the parent's children.
|
872
901
|
*/
|
873
902
|
function convertFromParentRect(parentBoundingRect, parentIntersectionRect) {
|
874
903
|
var top = parentIntersectionRect.top - parentBoundingRect.top;
|