-
Notifications
You must be signed in to change notification settings - Fork 3.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make inabox host correctly get position of a nested iframe #20599
Conversation
thanks @zombifier for the quick fix! will take a look later today. Meantime, have you checked the local example mentioned in #14010 with your fix? |
I had, and it works. |
awesome. is it easy to add an integration test ? |
I can try; the main issue is that the main test iframe is scrollable and by default much smaller than the browser window, so even if the creative is not visible it could technically still be within the size of the viewport and trigger viewability. I can try to see if resizing the test iframe to full height can help. Visibility detection in general does not work properly if any of the nested iframes can be scrolled so its content enter the viewport rectangle while remaining invisible (and it's more or less impossible to do so without native IntersectionObserver), but that's not the case we ever need to worry about outside of testing. |
I should probably add some unit tests though. |
Might be hard for unit test to simulate the nested iframe situation though. |
ads/inabox/position-observer.js
Outdated
|
||
/** | ||
* Get the element's layout rect relative to the viewport. | ||
* If parentWin is provided, then attempt to walk up the DOM and add the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shall we just always walk up to the host window?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the parentWin parameter has to be provided, since this is a general-purpose position observer and there's no way to get the immediate window/iframe that contains the observed element.
I can change it so that if parentWin is not provided then automatically assume the host window to be its immediate parent. What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does targetElement.ownerDocument.defaultView
not work?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TIL. I will try that. If it works then the parameter wouldn't be needed.
ads/inabox/position-observer.js
Outdated
export function getTargetRect(element, parentWin) { | ||
let targetRect = layoutRectFromDomRect(element./*OK*/getBoundingClientRect()); | ||
if (parentWin) { | ||
for (let j = 0, tempWin = parentWin; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: while
loop might fit better here?
ads/inabox/position-observer.js
Outdated
let targetRect = layoutRectFromDomRect(element./*OK*/getBoundingClientRect()); | ||
if (parentWin) { | ||
for (let j = 0, tempWin = parentWin; | ||
j < 10 && tempWin != tempWin.top; j++, tempWin = tempWin.parent) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so the assumption is tempWin.top
is the host window? I feel it's not that reliable. Any better way?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree. The host window is the window that has the position observer installed, so I moved the function into the class and have the DOM climb stop at that window. The top condition remains just in case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sorry, I still didn't quite get it. where is the code to stop the DOM climb at host window?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah, sorry, was looking at outdated file.
Removing myself, since the latest commit doesn't seem to increase the bundle size. Feel free to re-add me if that's not the case. |
Since the amp-inabox integration tests are in nested iframe mode, if they're successfully reenabled on Safari I think that's a good enough integration test for this PR. I'm not pushing the commit until Sauce is reenabled on master, but manual local Sauce testing seems to confirm that it works. |
that sounds good. thanks for checking |
@lannka Is this ready? I resolved all the flaky tests by merging with upstream. |
Merged, good work! |
… observer is not null.
…t#20599) * Make inabox host correctly get position of a nested iframe Fixes ampproject#14010. * Fix unused import * Fix the existing unit test * Add a unit test for getFrameRect and fix fatal typo in loop body * oops * oops pt. 2 * Don't assume the top window is the host. * Use element.ownerDocument.defaultView to get the parent window of an element * lint
…main (#20459) * Make inabox-viewport measure the top level window directly if same domain Instead of sending a post message, if the inabox iframe can directly measure the host window then have it get its position directly from there. * fix types * Fix presubmit * Test disconnect function * Fix lint in new test * Try enabling friendly, no host script inabox test on Safari * Trivial fix to rerun Travis * Try the no host script test with the example AMP ad Checking if the serve mode of the example AMP test is changed somehow * don't whitelist the iframe * More work * Fix lint * Fix lint in test * fix oops * Throttle the listeners * Use the existing inabox host observer instead of rewriting a new one This makes the code cleaner and changes in the future easier * fix type issue * Revert the changes to test-amp-inabox.js I believe that the while the integration tests do test the inabox host script, they're are not actually testing the local AMP inabox run time. This might have to be fixed in a separate PR. * Gate the behavior behind experiment, and move canInspectWindow to helper file * Integrate the changes in #20599, and make sure the position observer is not null. * Inline the function * Fix type * Disconnect observer properly, and add a TODO to investigate a quirk in the listener. Specifically, why is Resources needed.
…t#20599) * Make inabox host correctly get position of a nested iframe Fixes ampproject#14010. * Fix unused import * Fix the existing unit test * Add a unit test for getFrameRect and fix fatal typo in loop body * oops * oops pt. 2 * Don't assume the top window is the host. * Use element.ownerDocument.defaultView to get the parent window of an element * lint
…main (ampproject#20459) * Make inabox-viewport measure the top level window directly if same domain Instead of sending a post message, if the inabox iframe can directly measure the host window then have it get its position directly from there. * fix types * Fix presubmit * Test disconnect function * Fix lint in new test * Try enabling friendly, no host script inabox test on Safari * Trivial fix to rerun Travis * Try the no host script test with the example AMP ad Checking if the serve mode of the example AMP test is changed somehow * don't whitelist the iframe * More work * Fix lint * Fix lint in test * fix oops * Throttle the listeners * Use the existing inabox host observer instead of rewriting a new one This makes the code cleaner and changes in the future easier * fix type issue * Revert the changes to test-amp-inabox.js I believe that the while the integration tests do test the inabox host script, they're are not actually testing the local AMP inabox run time. This might have to be fixed in a separate PR. * Gate the behavior behind experiment, and move canInspectWindow to helper file * Integrate the changes in ampproject#20599, and make sure the position observer is not null. * Inline the function * Fix type * Disconnect observer properly, and add a TODO to investigate a quirk in the listener. Specifically, why is Resources needed.
…main (ampproject#20459) * Make inabox-viewport measure the top level window directly if same domain Instead of sending a post message, if the inabox iframe can directly measure the host window then have it get its position directly from there. * fix types * Fix presubmit * Test disconnect function * Fix lint in new test * Try enabling friendly, no host script inabox test on Safari * Trivial fix to rerun Travis * Try the no host script test with the example AMP ad Checking if the serve mode of the example AMP test is changed somehow * don't whitelist the iframe * More work * Fix lint * Fix lint in test * fix oops * Throttle the listeners * Use the existing inabox host observer instead of rewriting a new one This makes the code cleaner and changes in the future easier * fix type issue * Revert the changes to test-amp-inabox.js I believe that the while the integration tests do test the inabox host script, they're are not actually testing the local AMP inabox run time. This might have to be fixed in a separate PR. * Gate the behavior behind experiment, and move canInspectWindow to helper file * Integrate the changes in ampproject#20599, and make sure the position observer is not null. * Inline the function * Fix type * Disconnect observer properly, and add a TODO to investigate a quirk in the listener. Specifically, why is Resources needed.
Fixes #14010.