-
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
Friendly frames embeds #4916
Friendly frames embeds #4916
Conversation
* 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 |
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.
Maybe name child
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.
Done
This looks very reasonable 👍 |
@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 |
You can use a base href, no? On Tue, Sep 13, 2016 at 9:01 AM, Dima Voytenko notifications@github.com
|
@cramforce Good point on BASE. I added it. PTAL. That solves |
Do we actually expect relative URLs in ads? On Tue, Sep 13, 2016 at 1:58 PM, Dima Voytenko notifications@github.com
|
Hard to tell. The signer will simply confirm and sign, not rewrite/optimize the content. Right? |
We at least reserialize and sign that. Not sure about resources. Definitely On Tue, Sep 13, 2016 at 4:33 PM, Dima Voytenko notifications@github.com
|
cc78ca5
to
656ac04
Compare
@cramforce This is ready for review. The "demo" files will be removed before merge (marked with /cc @tdrl @michaelkleber @bobcassels @lannka @avimehta For what's coming for friendly iframes. |
+a4a-cam On Thu, Sep 15, 2016 at 4:57 PM, Dima Voytenko notifications@github.com
Terran Lane email: tdrl@google.com |
export function getFrameElement(win) { | ||
try { | ||
return win.frameElement; | ||
} catch (e) { |
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.
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?
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.
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?
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.
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.
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 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?
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.
Lets keep it.
childDoc.open(); | ||
childDoc.write(spec.html); | ||
childDoc.close(); | ||
readyPromise = Promise.resolve(); |
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.
Document
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.
Done
const childDoc = childWin.document; | ||
|
||
// Add <BASE> tag. | ||
childDoc.head.appendChild(createElementWithAttributes( |
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.
Don't we have to do this earlier?
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.
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.
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.
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.
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.
Good point. I will update.
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.
Done
} | ||
|
||
|
||
/** |
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.
Add docs
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.
Done
|
||
// Go up the window hierarchy through friendly iframes. | ||
const win = (el.ownerDocument || el).defaultView; | ||
if (win && win != this.win_ && getTopWindow(win) == this.win_) { |
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.
Can we tag the window with something like win.ownedByParent
?
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.
That's what getTopWindow
does. The window has __AMP_TOP
property and this is what used here. I just hid it behind API.
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.
Makes sense.
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.
Same logic as https://github.com/ampproject/amphtml/pull/4916/files#diff-b596009fc4aa42dfa7d85c56dccf78eeR125? Can we extract this into a helper?
89b323a
to
0d089ec
Compare
@cramforce all changes have been done. PTAL. |
LGTM |
} | ||
return readyPromise.then(() => { | ||
// Add extensions. | ||
extensionsFor(win).installExtensionsInChildWindow( |
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.
We already have extensions
variable.
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.
Done
* @param {!FriendlyIframeSpec} spec | ||
* @visibleForTesting | ||
*/ | ||
export function mergeHtmlForTesting(spec) { |
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.
Why not just expose the mergeHtml
function?
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.
mergeHtmlForTesting
will be DCE'd. This way:
- I don't need to worry about anyone ignoring
@visibleForTesting
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) { |
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.
Can you comment how this works?
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.
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_) { |
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.
Same logic as https://github.com/ampproject/amphtml/pull/4916/files#diff-b596009fc4aa42dfa7d85c56dccf78eeR125? Can we extract this into a helper?
* Friendly iframe embed system * getFrameElement refactored to include parent tests
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: