Skip to content

Commit

Permalink
Include userActivation in the 3p iframe postMessage (ampproject#22627)
Browse files Browse the repository at this point in the history
* Include userActivation in the 3p iframe postMessage

* Suppress the failing type check.
  • Loading branch information
lannka authored May 31, 2019
1 parent 7d01572 commit 0d066cb
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 38 deletions.
47 changes: 37 additions & 10 deletions 3p/iframe-messaging-client.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,19 +120,38 @@ export class IframeMessagingClient {
}

/**
* Send a postMessage to Host Window
* @param {string} type The type of message to send.
* @param {JsonObject=} opt_payload The payload of message to send.
* Send a postMessage to Host Window
* @param {string} type The type of message to send.
* @param {JsonObject=} opt_payload The payload of message to send.
*/
sendMessage(type, opt_payload) {
const msg = serializeMessage(
type,
dev().assertString(this.sentinel_),
opt_payload,
this.rtvVersion_
);

// opt in the userActivation feature
// see https://github.com/dtapuska/useractivation
if (this.isMessageOptionsSupported_()) {
this.postMessageWithUserActivation_(msg);
} else {
this.hostWindow_./*OK*/ postMessage(msg, '*');
}
}

/**
* @param {string} msg
* @suppress {checkTypes} // Can be removed after closure compiler update their externs.
*/
postMessageWithUserActivation_(msg) {
this.hostWindow_./*OK*/ postMessage(
serializeMessage(
type,
dev().assertString(this.sentinel_),
opt_payload,
this.rtvVersion_
),
'*'
msg,
dict({
'targetOrigin': '*',
'includeUserActivation': true,
})
);
}

Expand Down Expand Up @@ -197,4 +216,12 @@ export class IframeMessagingClient {
this.observableFor_[messageType].fire(message);
}
}

/**
* @return {boolean}
*/
isMessageOptionsSupported_() {
// Learned from https://github.com/dtapuska/useractivation
return this.hostWindow_ && this.hostWindow_.postMessage.length == 1;
}
}
17 changes: 11 additions & 6 deletions test/integration/test-amp-ad-3p.js
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,7 @@ describe.configure().run('amp-ad 3P', () => {
.then(() => {
// test iframe will send out render-start to amp-ad
return poll('render-start message received', () => {
return fixture.messages.filter(message => {
return message.type == 'render-start';
}).length;
return !!fixture.messages.getFirstMessageEventOfType('render-start');
});
})
.then(() => {
Expand All @@ -168,12 +166,19 @@ describe.configure().run('amp-ad 3P', () => {
expect(iframe.contentWindow.ping.resizeSuccess).to.be.undefined;
iframe.contentWindow.context.requestResize(200, 50);
return poll('wait for embed-size to be received', () => {
return fixture.messages.filter(message => {
return message.type == 'embed-size';
}).length;
return !!fixture.messages.getFirstMessageEventOfType('embed-size');
});
})
.then(() => {
// The userActivation feature is known to be available on Chrome 74+
if (platform.isChrome() && platform.getMajorVersion() >= 74) {
const event = fixture.messages.getFirstMessageEventOfType(
'embed-size'
);
expect(event.userActivation).to.be.ok;
expect(event.userActivation.isActive).to.be.a('boolean');
}

return poll(
'wait for attemptChangeSize',
() => {
Expand Down
69 changes: 47 additions & 22 deletions testing/iframe.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ export function createFixtureIframe(
[BindEvents.RESCAN_TEMPLATE]: 0,
[FormEvents.SERVICE_INIT]: 0,
};
const messages = [];
let html = __html__[fixture] // eslint-disable-line no-undef
.replace(
/__TEST_SERVER_PORT__/g,
Expand Down Expand Up @@ -104,18 +103,7 @@ export function createFixtureIframe(
if (opt_beforeLoad) {
opt_beforeLoad(win);
}
win.addEventListener('message', event => {
const parsedData = parseMessageData(event.data);

if (
parsedData &&
// Either non-3P or 3P variant of the sentinel.
(/^amp/.test(parsedData.sentinel) ||
/^\d+-\d+$/.test(parsedData.sentinel))
) {
messages.push(parsedData);
}
});
const messages = new MessageReceiver(win);
// Function that returns a promise for when the given event fired at
// least count times.
const awaitEvent = (eventName, count) => {
Expand Down Expand Up @@ -602,14 +590,51 @@ export function maybeSwitchToCompiledJs(html) {
return html;
}

/**
* @param {*} data
* @return {?}
* @private
*/
function parseMessageData(data) {
if (typeof data == 'string' && isAmpMessage(data)) {
return deserializeMessage(data);
class MessageReceiver {
/**
* @param {!Window} win
*/
constructor(win) {
this.events_ = [];
win.addEventListener('message', event => {
const parsedData = this.parseMessageData_(event.data);

if (
parsedData &&
// Either non-3P or 3P variant of the sentinel.
(/^amp/.test(parsedData.sentinel) ||
/^\d+-\d+$/.test(parsedData.sentinel))
) {
this.events_.push({
data: parsedData,
userActivation: event.userActivation,
});
}
});
}

/**
* @param {string} type
* @returns {?Event}
*/
getFirstMessageEventOfType(type) {
for (let i = 0; i < this.events_.length; ++i) {
if (this.events_[i].data.type === type) {
return this.events_[i];
}
}
return null;
}

/**
* @param {*} data
* @return {?}
* @private
*/
parseMessageData_(data) {
if (typeof data == 'string' && isAmpMessage(data)) {
return deserializeMessage(data);
}
return data;
}
return data;
}

0 comments on commit 0d066cb

Please sign in to comment.