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

Friendly frames embeds #4916

Merged
merged 2 commits into from
Sep 16, 2016
Merged

Friendly frames embeds #4916

merged 2 commits into from
Sep 16, 2016

Conversation

dvoytenko
Copy link
Contributor

@dvoytenko dvoytenko commented Sep 10, 2016

Partial for #4915.

This outlines major changes for "friendly frames" support. It also contains a manual test setup to demonstrate the use of the API. Let's discuss before tests. Some important points:

  1. Boundary traversal rules: who and when is allowed traversal
  2. Analytics will have to have some major changes to support friendly frames (although it'd have to have the same for shadow DOM as well)
  3. Things like UrlReplacements are still very unclear. Specifically we probably shouldn't allow a blanket access to parent document's URL vars - some scoping is necessary. Likewise, shadow DOM has the same issues most likely.

* Copies the specified element to child window (friendly iframe). This way
* all implementations of the AMP elements are shared between all friendly
* frames.
* @param {!Window} win
Copy link
Member

Choose a reason for hiding this comment

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

Maybe name child

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

This looks very reasonable 👍

@dvoytenko
Copy link
Contributor Author

@cramforce So, another thing that will be an issue as well is URL resolution. E.g. resolving child element's relative URLs, as in the case with amp-img and even basic links.

@cramforce
Copy link
Member

You can use a base href, no?

On Tue, Sep 13, 2016 at 9:01 AM, Dima Voytenko notifications@github.com
wrote:

@cramforce https://github.com/cramforce So, another thing that will be
an issue as well is URL resolution. E.g. resolving child element's relative
URLs, as in the case with amp-img and even basic links.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#4916 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAFeT8GEnNkEl79rKjGZ02DeENlx6fjSks5qpsj0gaJpZM4J5k6k
.

@dvoytenko
Copy link
Contributor Author

@cramforce Good point on BASE. I added it. PTAL.

That solves <a> and similar issues. But doesn't solve the parseUrl and similar calls in the url.js, which are many.

@cramforce
Copy link
Member

Do we actually expect relative URLs in ads?

On Tue, Sep 13, 2016 at 1:58 PM, Dima Voytenko notifications@github.com
wrote:

@cramforce https://github.com/cramforce Good point on BASE. I added it.
PTAL.

That solves and similar issues. But doesn't solve the parseUrl and
similar calls in the url.js, which are many.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#4916 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAFeT38DA5ycVHlftFhiQcXSPBQ9QnjSks5qpw6HgaJpZM4J5k6k
.

@dvoytenko
Copy link
Contributor Author

@cramforce

Do we actually expect relative URLs in ads?

Hard to tell. The signer will simply confirm and sign, not rewrite/optimize the content. Right?

@cramforce
Copy link
Member

We at least reserialize and sign that. Not sure about resources. Definitely
right now things would only work with absolute URLs.

On Tue, Sep 13, 2016 at 4:33 PM, Dima Voytenko notifications@github.com
wrote:

@cramforce https://github.com/cramforce

Do we actually expect relative URLs in ads?

Hard to tell. The signer will simply confirm and sign, not
rewrite/optimize the content. Right?


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#4916 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAFeT-RexBzt60YIpXlBYiLQQRXyhQXNks5qpzK2gaJpZM4J5k6k
.

@dvoytenko dvoytenko force-pushed the ife1 branch 5 times, most recently from cc78ca5 to 656ac04 Compare September 15, 2016 20:42
@dvoytenko dvoytenko changed the title [DO NOT SUBMIT] prototype for friendly frames Prototype for friendly frames Sep 15, 2016
@dvoytenko dvoytenko changed the title Prototype for friendly frames Friendly frames embeds Sep 15, 2016
@dvoytenko
Copy link
Contributor Author

@cramforce This is ready for review. The "demo" files will be removed before merge (marked with DO NOT SUBMIT).

/cc @tdrl @michaelkleber @bobcassels @lannka @avimehta For what's coming for friendly iframes.

@tdrl
Copy link

tdrl commented Sep 15, 2016

+a4a-cam

On Thu, Sep 15, 2016 at 4:57 PM, Dima Voytenko notifications@github.com
wrote:

@cramforce https://github.com/cramforce This is ready for review. The
"demo" files will be removed before merge (marked with DO NOT SUBMIT).

/cc @tdrl https://github.com/tdrl @michaelkleber
https://github.com/michaelkleber @bobcassels
https://github.com/bobcassels @lannka https://github.com/lannka
@avimehta https://github.com/avimehta For what's coming for friendly
iframes.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#4916 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AQ4oaKx0nkpijUM80z4pg9zji7wMAIMdks5qqbEpgaJpZM4J5k6k
.

Terran Lane email: tdrl@google.com
Google Cambridge, MA Publisher Tags & Ads Latency team
"But I don't want to go among mad people," Alice remarked.
"Oh, you can't help that," said the Cat: "we're all mad here. I'm
mad. You're mad."
"How do you know I'm mad?" said Alice.
"You must be," said the Cat, "or you wouldn't have come here."

export function getFrameElement(win) {
try {
return win.frameElement;
} catch (e) {
Copy link
Member

Choose a reason for hiding this comment

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

In Safari this would yield a logged error independent of the catch. Can we instead only call the function when we know we are allowed to call it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Could you clarify? When we call this method, we already know for certain that the window belongs to a friendly iframe. How else can we protect against an error here?

Copy link
Member

Choose a reason for hiding this comment

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

Please document that that is the contract. If we only call this when we know it will work, then it is fine. Although I wonder then why we would have a try block.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I thought you were just concerned about failures on some random browser. Originally there wasn't a try/catch. Really by the time I check frameElement in all cases, I'm already 100% sure I'm working with a friendly frame. I can either kill this method, or do defense in depth here and check that this iframe been marked as friendly. WDYT?

Copy link
Member

Choose a reason for hiding this comment

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

Lets keep it.

childDoc.open();
childDoc.write(spec.html);
childDoc.close();
readyPromise = Promise.resolve();
Copy link
Member

Choose a reason for hiding this comment

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

Document

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

const childDoc = childWin.document;

// Add <BASE> tag.
childDoc.head.appendChild(createElementWithAttributes(
Copy link
Member

Choose a reason for hiding this comment

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

Don't we have to do this earlier?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Well, we could try, but the document is not visible yet and not functional - none of the extensions have been installed. Thus this is still a good time to do it, imo. And it's a lot easier than trying to insert it into a HTML string.

Copy link
Member

Choose a reason for hiding this comment

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

If there is anything in the doc directly in would potentially go to a different URL, though. I think we should either add it early or never.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point. I will update.

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

}


/**
Copy link
Member

Choose a reason for hiding this comment

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

Add docs

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


// Go up the window hierarchy through friendly iframes.
const win = (el.ownerDocument || el).defaultView;
if (win && win != this.win_ && getTopWindow(win) == this.win_) {
Copy link
Member

Choose a reason for hiding this comment

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

Can we tag the window with something like win.ownedByParent?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's what getTopWindow does. The window has __AMP_TOP property and this is what used here. I just hid it behind API.

Copy link
Member

Choose a reason for hiding this comment

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

Makes sense.

Copy link
Contributor

Choose a reason for hiding this comment

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

@dvoytenko dvoytenko force-pushed the ife1 branch 2 times, most recently from 89b323a to 0d089ec Compare September 16, 2016 16:51
@dvoytenko
Copy link
Contributor Author

@cramforce all changes have been done. PTAL.

@cramforce
Copy link
Member

LGTM

@cramforce cramforce added the LGTM label Sep 16, 2016
}
return readyPromise.then(() => {
// Add extensions.
extensionsFor(win).installExtensionsInChildWindow(
Copy link
Contributor

Choose a reason for hiding this comment

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

We already have extensions variable.

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

* @param {!FriendlyIframeSpec} spec
* @visibleForTesting
*/
export function mergeHtmlForTesting(spec) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not just expose the mergeHtml function?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

mergeHtmlForTesting will be DCE'd. This way:

  1. I don't need to worry about anyone ignoring @visibleForTesting
  2. mergeHtml will be obfuscated.

@@ -120,6 +120,17 @@ export class AmpDocService {
}
}

// Traverse the boundary of a friendly iframe.
const win = (n.ownerDocument || n).defaultView;
if (win && win != this.win && getTopWindow(win) == this.win) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you comment how this works?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good idea. I refactored it into a common method and added docs there.


// Go up the window hierarchy through friendly iframes.
const win = (el.ownerDocument || el).defaultView;
if (win && win != this.win_ && getTopWindow(win) == this.win_) {
Copy link
Contributor

Choose a reason for hiding this comment

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

@dvoytenko dvoytenko merged commit d50eeae into ampproject:master Sep 16, 2016
@dvoytenko dvoytenko deleted the ife1 branch September 16, 2016 22:39
mityaha pushed a commit to ooyala/amphtml that referenced this pull request Nov 30, 2016
* Friendly iframe embed system

* getFrameElement refactored to include parent tests
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.

4 participants