Skip to content

Commit

Permalink
馃悰 Report zero visibility for zero size element (ampproject#30105)
Browse files Browse the repository at this point in the history
* check belement size before setting visible percentage

* fix test

* nit
  • Loading branch information
zhouyx authored and ed-bird committed Dec 10, 2020
1 parent c86f892 commit ffb0bca
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 4 deletions.
9 changes: 8 additions & 1 deletion extensions/amp-analytics/0.1/test/test-amp-analytics.js
Original file line number Diff line number Diff line change
Expand Up @@ -1468,8 +1468,11 @@ describes.realWin(
describe('Sandbox AMP Analytics Element', () => {
beforeEach(() => {
// Unfortunately need to fake sandbox analytics element's parent
// to an AMP element
// to an AMP element.
// Set the doc width/height to 1 to trigger visible event.
doc.body.classList.add('i-amphtml-element');
doc.body.style.minWidth = '1px';
doc.body.style.minHeight = '1px';
});

afterEach(() => {
Expand Down Expand Up @@ -1751,6 +1754,10 @@ describes.realWin(
describe('parentPostMessage', () => {
let postMessageSpy;

beforeEach(() => {
doc.body.style.minWidth = '1px';
doc.body.style.minHeight = '1px';
});
function waitForParentPostMessage(opt_max) {
if (postMessageSpy.callCount) {
return Promise.resolve();
Expand Down
60 changes: 60 additions & 0 deletions extensions/amp-analytics/0.1/test/test-visibility-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ describes.fakeWin('VisibilityManagerForDoc', {amp: true}, (env) => {
target: otherTarget,
intersectionRatio: 0.3,
intersectionRect: layoutRectLtwh(0, 0, 1, 1),
boundingClientRect: layoutRectLtwh(1, 1, 1, 1),
},
]);
expect(root.getRootVisibility()).to.equal(0);
Expand All @@ -212,11 +213,13 @@ describes.fakeWin('VisibilityManagerForDoc', {amp: true}, (env) => {
target: otherTarget,
intersectionRatio: 0.5,
intersectionRect: layoutRectLtwh(0, 0, 1, 1),
boundingClientRect: layoutRectLtwh(1, 1, 1, 1),
},
{
target: win.document.documentElement,
intersectionRatio: 0.3,
intersectionRect: layoutRectLtwh(0, 0, 1, 1),
boundingClientRect: layoutRectLtwh(1, 1, 1, 1),
},
]);
expect(root.getRootVisibility()).to.equal(0.3);
Expand All @@ -227,6 +230,7 @@ describes.fakeWin('VisibilityManagerForDoc', {amp: true}, (env) => {
target: win.document.documentElement,
intersectionRatio: 0,
intersectionRect: layoutRectLtwh(0, 0, 0, 0),
boundingClientRect: layoutRectLtwh(1, 1, 1, 1),
},
]);
expect(root.getRootVisibility()).to.equal(0);
Expand Down Expand Up @@ -525,6 +529,7 @@ describes.fakeWin('VisibilityManagerForDoc', {amp: true}, (env) => {
target,
intersectionRatio: 0.3,
intersectionRect: layoutRectLtwh(0, 0, 1, 1),
boundingClientRect: layoutRectLtwh(1, 1, 1, 1),
},
]);
expect(model.getVisibility_()).to.equal(0.3);
Expand Down Expand Up @@ -569,6 +574,7 @@ describes.fakeWin('VisibilityManagerForDoc', {amp: true}, (env) => {
target,
intersectionRatio: 0.3,
intersectionRect: layoutRectLtwh(0, 0, 1, 1),
boundingClientRect: layoutRectLtwh(1, 1, 1, 1),
},
]);
expect(model.getVisibility_()).to.equal(0.3);
Expand All @@ -579,6 +585,7 @@ describes.fakeWin('VisibilityManagerForDoc', {amp: true}, (env) => {
target,
intersectionRatio: -0.01,
intersectionRect: layoutRectLtwh(0, 0, 1, 1),
boundingClientRect: layoutRectLtwh(1, 1, 1, 1),
},
]);
expect(model.getVisibility_()).to.equal(0);
Expand All @@ -588,6 +595,7 @@ describes.fakeWin('VisibilityManagerForDoc', {amp: true}, (env) => {
target,
intersectionRatio: -1000,
intersectionRect: layoutRectLtwh(0, 0, 1, 1),
boundingClientRect: layoutRectLtwh(1, 1, 1, 1),
},
]);
expect(model.getVisibility_()).to.equal(0);
Expand All @@ -598,6 +606,7 @@ describes.fakeWin('VisibilityManagerForDoc', {amp: true}, (env) => {
target,
intersectionRatio: 1.01,
intersectionRect: layoutRectLtwh(0, 0, 1, 1),
boundingClientRect: layoutRectLtwh(1, 1, 1, 1),
},
]);
expect(model.getVisibility_()).to.equal(1);
Expand All @@ -607,11 +616,55 @@ describes.fakeWin('VisibilityManagerForDoc', {amp: true}, (env) => {
target,
intersectionRatio: 1000,
intersectionRect: layoutRectLtwh(0, 0, 1, 1),
boundingClientRect: layoutRectLtwh(1, 1, 1, 1),
},
]);
expect(model.getVisibility_()).to.equal(1);
});

it('should protect from zero size element', () => {
const target = win.document.createElement('div');
root.listenElement(target, {}, null, null, eventResolver);
expect(root.models_).to.have.length(1);
const model = root.models_[0];

const inOb = root.getIntersectionObserver_();
expect(model.getVisibility_()).to.equal(0);

// Valid element size
inOb.callback([
{
target,
intersectionRatio: 1,
intersectionRect: layoutRectLtwh(0, 0, 1, 1),
boundingClientRect: layoutRectLtwh(1, 1, 10, 10),
},
]);
expect(model.getVisibility_()).to.equal(1);

// zero element size.
inOb.callback([
{
target,
intersectionRatio: 1,
intersectionRect: layoutRectLtwh(0, 0, 1, 1),
boundingClientRect: layoutRectLtwh(1, 1, 0, 10),
},
]);
expect(model.getVisibility_()).to.equal(0);

// zero element size, high resolution screen.
inOb.callback([
{
target,
intersectionRatio: 0.8,
intersectionRect: layoutRectLtwh(0, 0, 1, 1),
boundingClientRect: layoutRectLtwh(1, 1, 10, 0.452),
},
]);
expect(model.getVisibility_()).to.equal(0);
});

it('should listen on a element with different specs', () => {
clock.tick(1);
const inOb = root.getIntersectionObserver_();
Expand All @@ -637,6 +690,7 @@ describes.fakeWin('VisibilityManagerForDoc', {amp: true}, (env) => {
target,
intersectionRatio: 0.3,
intersectionRect: layoutRectLtwh(0, 0, 1, 1),
boundingClientRect: layoutRectLtwh(1, 1, 1, 1),
},
]);
expect(model1.getVisibility_()).to.equal(0.3);
Expand Down Expand Up @@ -712,6 +766,7 @@ describes.fakeWin('VisibilityManagerForDoc', {amp: true}, (env) => {
target,
intersectionRatio: 0.3,
intersectionRect: layoutRectLtwh(0, 0, 1, 1),
boundingClientRect: layoutRectLtwh(1, 1, 1, 1),
},
]);

Expand Down Expand Up @@ -895,6 +950,7 @@ describes.realWin(
target: embed.host,
intersectionRatio: 0.5,
intersectionRect: layoutRectLtwh(0, 0, 1, 1),
boundingClientRect: layoutRectLtwh(1, 1, 1, 1),
},
]);
expect(root.getRootVisibility()).to.equal(0.5);
Expand All @@ -907,6 +963,7 @@ describes.realWin(
target: otherTarget,
intersectionRatio: 0.45,
intersectionRect: layoutRectLtwh(0, 0, 1, 1),
boundingClientRect: layoutRectLtwh(1, 1, 1, 1),
},
]);
expect(root.getRootVisibility()).to.equal(0.5);
Expand All @@ -933,6 +990,7 @@ describes.realWin(
target: embed.host,
intersectionRatio: 0,
intersectionRect: layoutRectLtwh(0, 0, 1, 1),
boundingClientRect: layoutRectLtwh(1, 1, 1, 1),
},
]);
expect(root.getRootVisibility()).to.equal(0);
Expand All @@ -945,6 +1003,7 @@ describes.realWin(
target: otherTarget,
intersectionRatio: 0.55,
intersectionRect: layoutRectLtwh(0, 0, 1, 1),
boundingClientRect: layoutRectLtwh(1, 1, 1, 1),
},
]);
expect(root.getRootVisibility()).to.equal(0);
Expand All @@ -957,6 +1016,7 @@ describes.realWin(
target: embed.host,
intersectionRatio: 0.7,
intersectionRect: layoutRectLtwh(0, 0, 1, 1),
boundingClientRect: layoutRectLtwh(1, 1, 1, 1),
},
]);
expect(root.getRootVisibility()).to.equal(0.7);
Expand Down
11 changes: 8 additions & 3 deletions extensions/amp-analytics/0.1/visibility-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -872,7 +872,6 @@ export class VisibilityManagerForDoc extends VisibilityManager {
Number(intersection.width),
Number(intersection.height)
);
// TODO(#29618): Remove after ampim investigation
let {boundingClientRect} = change;
boundingClientRect =
boundingClientRect &&
Expand All @@ -892,7 +891,6 @@ export class VisibilityManagerForDoc extends VisibilityManager {
}

/**
* TODO(#29618): Clean up boundingClientRect after ampim investigation
* @param {!Element} target
* @param {number} intersectionRatio
* @param {!../../../src/layout-rect.LayoutRectDef} intersectionRect
Expand All @@ -905,9 +903,16 @@ export class VisibilityManagerForDoc extends VisibilityManager {
intersectionRect,
boundingClientRect
) {
intersectionRatio = Math.min(Math.max(intersectionRatio, 0), 1);
const id = getElementId(target);
const trackedElement = this.trackedElements_[id];
if (boundingClientRect.width < 1 || boundingClientRect.height < 1) {
// Set intersectionRatio to 0 when the element is not visible.
// Use < 1 because the width/height can
// be a double value on high resolution screen
intersectionRatio = 0;
} else {
intersectionRatio = Math.min(Math.max(intersectionRatio, 0), 1);
}
if (trackedElement) {
trackedElement.intersectionRatio = intersectionRatio;
trackedElement.intersectionRect = intersectionRect;
Expand Down

0 comments on commit ffb0bca

Please sign in to comment.