Skip to content

Pass context down for a4a ad rendering to allow window.context to function#7132

Merged
lannka merged 34 commits intoampproject:masterfrom
google:frizz-a4a-pass-context
Feb 2, 2017
Merged

Pass context down for a4a ad rendering to allow window.context to function#7132
lannka merged 34 commits intoampproject:masterfrom
google:frizz-a4a-pass-context

Conversation

@bradfrizzell
Copy link
Copy Markdown
Contributor

@bradfrizzell bradfrizzell commented Jan 20, 2017

No description provided.

@@ -0,0 +1,25 @@
<!doctype html>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is this file supposed to be part of this PR?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

no this shouldn't be. removed

}, SHARED_IFRAME_PROPERTIES));
const sentinel = generateSentinel(window);
const metadata = getContextMetadata(window, iframe, sentinel);
iframe.setAttribute('name', encodeURIComponent(JSON.stringify(metadata)));
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why encodeURIComponent?

Copy link
Copy Markdown
Contributor Author

@bradfrizzell bradfrizzell Jan 23, 2017

Choose a reason for hiding this comment

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

because this is getting written to the name attribute in the html, this was to protect against if anything in the metadata has a closing quote

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why would it matter if something had a closing quote?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

My concern is an XSS injection, because we're writing this data into the page that could contain in the JSON a bunch of stuff that we're not controlling. So I meant that they could close the quote on the name attribute, and then like open a script tag or something. Like if the json object was:

{"foo":"<script>alert("foo");</script>}

that would be written right in the page.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

DOM manipulation doesn't work that way. iframe.setAttribute('name', someString) will never change anything other than the value of iframe.name no matter what's in someString.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

ok. if there's no risk then I guess we don't need encodeURIComponent

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

done

'src': srcPath,
'name': nameData,
}, SHARED_IFRAME_PROPERTIES));
if (method == XORIGIN_MODE.NAMEFRAME){
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Add a space before the brace.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

done

if (method == XORIGIN_MODE.NAMEFRAME){
const sentinel = generateSentinel(window);
const metadata = getContextMetadata(window, iframe, sentinel);
let name = JSON.stringify({creative, _context: metadata._context});
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

const, since it doesn't change. Also, I'd prefer for these string keys to be quoted; even if the actual Closure rules (which I don't fully understand) don't allow renaming of fields under these circumstances, it's better for no one reading the code to have to wonder about that.

Copy link
Copy Markdown
Contributor Author

@bradfrizzell bradfrizzell Jan 23, 2017

Choose a reason for hiding this comment

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

done, changed it so both creative and _context are the name of the local variable, so they variables are the keys and we don't need the strings anyways

* @param {!Window} parentWindow
* @param {!Element} element
* @return {!Object} Contains
* precedence over the data- attributes.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Did something get incorrectly copy-pasted here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

yes that's screwed up, but this file actually also should not be in this PR (although it is needed for this pr). #7129 is where I am creating it, and this PR should block on that one's merging

@bradfrizzell bradfrizzell changed the title WIP - Pass context down for a4a ad rendering to allow window.context to function Pass context down for a4a ad rendering to allow window.context to function Jan 24, 2017
@bradfrizzell
Copy link
Copy Markdown
Contributor Author

Upon talking to keith, we are going to ignore the safeframe case for now and just focus on getting this working for nameframe and direct frame

@bradfrizzell
Copy link
Copy Markdown
Contributor Author

blocked by #7129

.then(() => this.noContent_());
}

this.element_.appendChild(this.iframe);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Appending this before setting all the styles could affect painting.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

would moving the setStyle line above the append be sufficient?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Yup.

}

this.element_.appendChild(this.iframe);
if (opt_isA4A) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why was this moved down?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This was moved down because we want to listen for the no content message in the a4a case.

}, SHARED_IFRAME_PROPERTIES));
if (method == XORIGIN_MODE.NAMEFRAME) {
const sentinel = generateSentinel(window);
const _context = getContextMetadata(window, iframe, sentinel)._context;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can we expose this as a method?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

sure. I put it in amp-a4a, but maybe this should go in iframe-attributes.js?

Copy link
Copy Markdown
Contributor

@lannka lannka left a comment

Choose a reason for hiding this comment

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

I'm wondering what the status of those various ways of delayed rendering: nameframe, safeframe, cachedcontent.

Do we plan to eventually eliminate them and keep one? Maintaining them is a bit costly.

@keithwrightbos

*/
generateSentinelAndContext(iframe) {
const sentinel = generateSentinel(window);
const context = getContextMetadata(window, iframe, sentinel)._context;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

return it directly?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

done

*/
generateSentinelAndContext(iframe) {
const sentinel = generateSentinel(window);
const context = getContextMetadata(window, iframe, sentinel)._context;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

looking at the impl of getContextMetadata, it seems weird that we're building an attributes object but end up using on one field of it. can't we just extract that part out as a separate method?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

this is actually a mistake, shouldn't be returning ._context, just the main object

if (opt_isA4A) {
this.element_.appendChild(this.iframe);
// A4A writes creative frame directly to page therefore does not expect
// post message to unset visibility hidden
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

not sure what the "post message" is here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I'm also not sure, this was a holdover comment. I don't think that this postmessage ever happens. I'm going to delete this comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

ah, i think it is referring to render-start and no-content events. Please update the doc.

setStyle(this.iframe, 'visibility', '');
if (this.baseInstance_.emitLifecycleEvent) {
this.baseInstance_.emitLifecycleEvent('adSlotUnhidden');
if (opt_isA4A) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

any reason to move this code? A4A creative in friendly iframe will not send 'render-start' event, so there's no need to listen to it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

because we want to register listening for 'no-content'

@keithwrightbos
Copy link
Copy Markdown
Contributor

Regarding xdomain write methods (cached, safeframe, nameframe): once nameframe shows same metrics as safeframe, we will no longer use sameframe methodology. We may keep the cached way as currently it shows better metrics than safeframe (this is expected given it requires less browser resources) however my SRA design will necessitate the use of nameframe. If we find that majority of requests use nameframe, we can also remove cached method.

3p/ampcontext.js Outdated
* @private
*/
getWindowSentinel_() {
this.sentinel = this.win_.AMP_SENTINEL || null;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'm wondering who will be setting window.AMP_SENTINEL

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

this is to allow a bypass with safeframe if needed, in which case we don't want to write on the sentinel or hash. instead we can write a script into the ad itself that sets this variable

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can we make that more explicit by changing AMP_SENTINEL to another name?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

changed to SAFEFRAME_SENTINEL

3p/ampcontext.js Outdated
this.setupMetadata_();
this.win_ = win;
if (!this.getWindowSentinel_()) {
this.setupMetadata_();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

can you add some doc to explain in what scenario we don't need to parse the metadata?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

done

3p/ampcontext.js Outdated
* @private
*/
getWindowSentinel_() {
this.sentinel = this.win_.AMP_SENTINEL || null;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can we make that more explicit by changing AMP_SENTINEL to another name?

if (opt_isA4A) {
this.element_.appendChild(this.iframe);
return Promise.resolve();
} else {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Unnecessary else.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

done

'name': nameData,
}, SHARED_IFRAME_PROPERTIES));
if (method == XORIGIN_MODE.NAMEFRAME) {
const attributes = this.generateSentinelAndContext(iframe);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Does this return a context or attributes?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I've been using it somewhat interchangeably, but sentinel and context together are the attributes assigned on the frame. 'context' is referring to the old context that did not include sentinel

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

what about renaming attributes to metadata, generateSentinelAndContext to generateMetadata?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I could do that, but there are a lot of other places that would have to change. could I do a cleanup refactoring PR for that? really need to finish this asap

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

A TODO works for me :-)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

done

const contentWindow = we.frame.contentWindow;
if (!contentWindow) {
setTimeout(dropListenSentinel, 0, listenSentinel);
} else if (sentinel === 'amp') {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

so, we end up removing this whole block for "sentinel==='amp''.
why was it affecting the A4A iframes? I don't think they have sentinel of 'amp', do they?

will this break our non-3p iframes which has sentinel = 'amp'?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

fixed

@bradfrizzell
Copy link
Copy Markdown
Contributor Author

In addition to the gulp tests, I also did manual testing on live pages and my example page to verify that direct frame and nameframe both set up properly and can send/receive postMessages to/from the runtime.

if (typeof this.win_.AMP_CONTEXT_DATA == 'string') {
this.sentinel = this.win_.AMP_CONTEXT_DATA;
} else {
this.setupMetadata_(this.win_.AMP_CONTEXT_DATA);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

now this method mutates states, so we should rename it.
And probably you will just want to move line 33 into this method as well.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

done

3p/ampcontext.js Outdated
/**
* Parse the metadata attributes from the name and add them to
* the class instance.
* @param {!Object|!String} contextData
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

{!Object|string} data

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

done

3p/ampcontext.js Outdated
this.referrer = context.referrer;
} catch (err) {
data = JSON.parse(decodeURI(data));
} catch (err) {}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

you can use tryParseJson() in json.js

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

done

3p/ampcontext.js Outdated
} catch (err) {}

if (!data || typeof data != 'object') {
user().error('AMPCONTEXT', '- Could not parse metadata.');
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

this is more likely a dev error? we actually can just skip it, since we are throwing in the next line.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

done

3p/ampcontext.js Outdated
data = JSON.parse(decodeURI(data));
} catch (err) {}

if (!data || typeof data != 'object') {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

no need to check typeof data

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

done

<br>
<br>
<br>
<br>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

why so many br? can you use a blank div instead?

Copy link
Copy Markdown
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
Copy Markdown

@tdrl tdrl left a comment

Choose a reason for hiding this comment

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

Mostly minor stuff and nits. The only one I'm really concerned about is the comment about overwriting name that's just been set. Otherwise, LGTM.

3p/ampcontext.js Outdated
this.setupMetadata_();
this.win_ = win;

// if the window sentinel is set directly, that means we are running
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Nit: Start with capital letter and end with a period.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

done

/**
* Checks to see if there is a window variable assigned with the
* sentinel value, sets it, and returns true if so.
* @private
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@return

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

removed return value

3p/ampcontext.js Outdated

// if the window sentinel is set directly, that means we are running
// in a situation where we couldn't attach the name attribute before
// creating the iframe, so don't try to parse the metadata
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Woo -- I'm not sure I can follow all the negatives here. Can you restate this in terms of positives -- when do you set the metadata?

I'm trying to decide if you're setting the sentinel in hasSafeframeSentinel and then overriding in setupMetadata. I don't think so, but I'm too foggy-headed this morning to work through the negatives and cases. :-)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

done

@@ -0,0 +1,88 @@
if (!window.context){
// window.context doesn't exist yet, must perform steps to create it
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Nit: end with period. (Here and below.)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

file deleted

// before using it
console.log("window.context NOT READY");

// must add listener for the creation of window.context
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Nit: Start with capital letter. (Here and below.)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

file deleted

expect(attributes._context).to.be.ok;
if (!attributes._context.amp3pSentinel) {
expect(attributes._context.sentinel).to.be.ok;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

So here you're saying that at least one of these should be present, right? Do you want to ensure that exactly one of them is present?

Perhaps a better way to structure this is to add an argument to verifyNameFrameRender that specifies which you should expect, given the case being tested. Then you can do something like:

function verifyNameFrameRender(element, expectSentinel) {
  // stuff
  expect(attributes._context).not.to.contain.all.keys('sentinel', 'amp3pSentinel');
  if (expectSentinel) {
    expect(attributes._context).to.contain.keys('sentinel');
    expect(attributes._context.sentinel).to.match(/some_regex/);
  } else {
    expect(attributes._context).to.contain.keys('amp3pSentinel');
    expect(attributes._context.amp3pSentinel).to.match(/some_regex/);
  }

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The two cases for sentinel naming will collapse down very soon, so I didn't want to modify the other tests too much. I can add additional logic in here as suggested for making sure it doesn't have both keys and that it matches the regex

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

SGTM.

const attributes = JSON.parse(nameData);
expect(attributes).to.be.ok;
expect(attributes._context).to.be.ok;
if (!attributes._context.amp3pSentinel) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Ah. You're doing essentially the same test here as above. I suggest factoring the nameData validation out to a common function that you call from both places.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

done


it('should be able to create AmpContext', () => {
return a4a.layoutCallback().then(() => {
const window_ = a4aElement.childNodes[0].contentWindow;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Probably safer to use a querySelector to get reference to the iframe, so that this test doesn't break if we add stuff to or rearrange the DOM structure under the a4a element.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

done


it('should be able to create AmpContext', () => {
return a4a.layoutCallback().then(() => {
const window_ = a4aElement.childNodes[0].contentWindow;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Ditto.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

done

.then(() => this.noContent_());
}

if (opt_isA4A) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Why did you move this down here? Does it depend on the listeners having already been set up? If so, should probably add a note about that dependency. Also, seems worth keeping the original comment -- I don't think it's deprecated. (?)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

because we want to listen for nocontent message for a4a. I'll add comment back in

Copy link
Copy Markdown
Contributor

@lannka lannka left a comment

Choose a reason for hiding this comment

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

LGTM, some minor comments.
I didn't take close look at the tests, which Terran is right now on. Please address them as well.

3p/ampcontext.js Outdated
} else {
this.setupMetadata_(this.win_.AMP_CONTEXT_DATA);
}
return !!this.sentinel;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

is return still needed?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

removed

src="http://localhost:8000/examples/ampcontext-creative.html">
</amp-ad>
<div>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

if all you want is space, you can do it via CSS. not sure if empty lines here would work

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

done


function intersectionCallback(payload){
changes = payload.changes;
// Step 4: Do something with the intersection updates!
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Nit: Still need to do something with "Step 4", b/c there's no 1..3 in this file.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

whooooops

Copy link
Copy Markdown

@tdrl tdrl left a comment

Choose a reason for hiding this comment

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

LGTM. Thanks!

@lannka lannka merged commit af90bed into ampproject:master Feb 2, 2017
torch2424 pushed a commit to torch2424/amphtml that referenced this pull request Feb 14, 2017
…ction (ampproject#7132)

* Created attributes.js

* Added context to direct frame rendering

* Added context to rendering via nameframe

* Removed unneeded files

* Fixed lint and naming

* Don't need to uriencode

* Modified tests

* Created generateSentinelAndContext and moved setStyle

* Fixed test breakages, handled sentinel name change experiment

* Addressed comments; ampContext now checks for window var; added/modified tests

* Added docstring

* Addressed comments

* Added test

* Attach data-amp-3p-sentinel attribute to frame

* Fix a4a frames not having messages processed correctly

* Added examples for manual testing

* Addressed comments'

* Revert "Addressed comments'"

This reverts commit a61ddf8.

* Changed name of function to hasSafeframeSentinel:

* Added todo

* Updated docstring and added todo

* Fixed getListenForEvents

* Collapse if block cases

* Undid change to getListenForEvents

* Fixed nameframe to keep context data on name

* Broke out isAmpMessage function to use for parsing

* Handle different ways of setting up AmpContext

* Make test page take up multiple viewports

* Fixed lint mistakes

* Inlined ampcontext-creative.js into html

* Addressed comments

* Addressed comments

* Add comments to explain setting of name on nameframe

* removed comment
mrjoro pushed a commit to mrjoro/amphtml that referenced this pull request Apr 28, 2017
…ction (ampproject#7132)

* Created attributes.js

* Added context to direct frame rendering

* Added context to rendering via nameframe

* Removed unneeded files

* Fixed lint and naming

* Don't need to uriencode

* Modified tests

* Created generateSentinelAndContext and moved setStyle

* Fixed test breakages, handled sentinel name change experiment

* Addressed comments; ampContext now checks for window var; added/modified tests

* Added docstring

* Addressed comments

* Added test

* Attach data-amp-3p-sentinel attribute to frame

* Fix a4a frames not having messages processed correctly

* Added examples for manual testing

* Addressed comments'

* Revert "Addressed comments'"

This reverts commit a61ddf8.

* Changed name of function to hasSafeframeSentinel:

* Added todo

* Updated docstring and added todo

* Fixed getListenForEvents

* Collapse if block cases

* Undid change to getListenForEvents

* Fixed nameframe to keep context data on name

* Broke out isAmpMessage function to use for parsing

* Handle different ways of setting up AmpContext

* Make test page take up multiple viewports

* Fixed lint mistakes

* Inlined ampcontext-creative.js into html

* Addressed comments

* Addressed comments

* Add comments to explain setting of name on nameframe

* removed comment
@bruscantini
Copy link
Copy Markdown
Contributor

Hi all. Can creatives now use this window.AMP_CONTEXT_DATA to get the top level url? An issue I keep having, from a creative standpoint, is trying to get the top level page url when inside a x-domain iframe. I've noticed if the x-domain iframe has domain *.ampproject.net I can get it by parsing the window.name JSON and eventually getting the sourceUrl value. Now, I've come across an occasion where I'm inside a safeframe and have an empty window.name property, but this AMP_CONTEXT_DATA is populated. Is there a consistent way for creatives to get the top page url from AMP? I raised this issue before in #12342.
Thanks for the help guys. :)

@bradfrizzell
Copy link
Copy Markdown
Contributor Author

hi @bruscantini

So as you've seen, in a safeframe setting, the window name is wiped clean before you have access to it, so GPT safeframe saves the amp context data onto that window var to allow for use later. To save yourself some hassle, you can just use the AmpContext library directly https://github.com/ampproject/amphtml/blob/master/3p/ampcontext.js which handles all the parsing for you. The binary is served as https://3p.ampproject.net/1518441587106/ampcontext-v0.js

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.

8 participants