Skip to content
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

Changes to postMessage code in AMP for nested iframe communication #3327

Merged
merged 14 commits into from
Jun 2, 2016

Conversation

nekodo
Copy link
Contributor

@nekodo nekodo commented May 25, 2016

First stage of implementing #3019. Switches the 3P messaging code to use a per-iframe sentinel as opposed to a per-release sentinel and adds an option to listen for messages not only from a given frame, but also from any nested frames within it (as long as they carry the correct sentinel).

As a first application, IntersectionObserver is modified to allow nested frames to request updates on the visibility of the top frame.

Note that this change will likely worsen the performance slightly:

  • we need to parse all messages to check sentinel, as contentWindow and origin are not sufficient to reject a message anymore
  • non-3P iframes are no longer looked up by origin
  • 3P iframes get an efficient lookup by a (likely) unique sentinel, but if they are nested then we need to walk the window hierarchy on each message

Fortunately we should be able to regain the performance by adding a WeakMap-based cache keyed by the source window so that we only need to do all these lookup on the first message from a window. To reduce complexity I left that for a follow up change.

@googlebot
Copy link

Thanks for your pull request. It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

📝 Please visit https://cla.developers.google.com/ to sign.

Once you've signed, please reply here (e.g. I signed it!) and we'll verify. Thanks.


  • If you've already signed a CLA, it's possible we don't have your GitHub username or you're using a different email address. Check your existing CLA data and verify that your email is set on your git commits.
  • If you signed the CLA as a corporation, please let us know the company's name.

for (let win = parentWindow; win != window.top; win = win.parent) {
windowDepth++;
}
return '' + windowDepth + '-' + Math.round(Math.random() * 1000000);
Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

@cramforce
Copy link
Member

@nekodo Very nice!
@jridgewell Do you want to take a quick look since you changed most of the code recently?

@jridgewell
Copy link
Contributor

Yup, I'll be taking a look at it today.

@cramforce
Copy link
Member

LGTM from me. We need to make sure to do good manual testing in canary.

*/
export function generateSentinel(parentWindow) {
let windowDepth = 0;
for (let win = parentWindow; win != window.top; win = win.parent) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Don't we usually use window !== window.parent for our checks?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Malte mentioned that window comparisons should use == rather than ===, I assumed the same for != vs !==.

Copy link
Contributor

Choose a reason for hiding this comment

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

The window.parent vs the current window.top was what I meant, sorry for the confusion.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right, I switched to a consistent pattern of navigating the window hierarchy using win!=win.parent to identify the top of the hierarchy.

// messages for it (
let listener = function(data, source, origin) {
// Exclude nested frames if necessary.
if (!opt_includingNestedWindows && source != iframe.contentWindow) {
Copy link

Choose a reason for hiding this comment

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

It might be worth adding a comment here that at this point, source is either iframe.contentWindow, or one of its child frames, and cannot be an unrelated window.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

@molnarg
Copy link

molnarg commented May 30, 2016

LGTM

@jridgewell
Copy link
Contributor

LGTM as well.

@cramforce cramforce added the LGTM label Jun 2, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants