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
Introduce iframe transport to amp-analytics - 3p side #10596
Merged
Merged
Changes from all commits
Commits
Show all changes
85 commits
Select commit
Hold shift + click to select a range
9a2c05e
Adds 3p iframe to amp analytics. Uses Subscription API. Event message…
jonkeller c539c66
Fix SubscriptionAPI
jonkeller 2f892c3
Brings in previous chanages to anchor-click-interceptor.js
jonkeller e754522
Adds unit tests
jonkeller be880d6
Updates queue unit tests
jonkeller 8c76838
Updates custom types and unit tests
jonkeller dbf2960
Adds misc small fixes/nits from self-review
jonkeller 7e58280
Changes 2 URLs in example from absolute to relative
jonkeller 5d46a9d
Comments only
jonkeller b6351f2
Fixes TODO re: unlayoutCallback destroying 3p iframe
jonkeller d15b9c5
Fixes an 80-char line length violation introduced in previous PR
jonkeller fb539c8
Implements review feedback
jonkeller f252fe1
Implements review feedback
jonkeller ab3b882
Addresses review feedback
jonkeller 8b47fb0
Reverts change to URL calculation, pending additional discussion
jonkeller b291ea1
Fixes unit test
jonkeller 8373e55
Fixes indentation of 2 lines
jonkeller e56dbed
Removes extraData, new creative message
jonkeller 83fa626
Fixes transport unit tests
jonkeller 8b5f533
Clarifies transport ID
jonkeller 88d118d
Fixes whitespace
jonkeller 5e4e3f7
Improves example triggers. Fixes issue of delivery of creative response
jonkeller 558339f
Makes indentation consistent in this section
jonkeller 305a84b
Addresses review feedback
jonkeller 421b56e
Fixes a null check
jonkeller c1b36b5
Keys off of type rather than URL. Fixes issue of null origin, without…
jonkeller e111811
Minor type annotation corrections
jonkeller e590d9e
Makes use of new param to SubscriptionAPI c'tor
jonkeller 4c17cbe
Removes allow-same-origin
jonkeller 3ce7c3b
Addresses review feedback, including removing response
jonkeller fbdb4a8
Fixes unit test
jonkeller f664d31
Adds a forgotten semicolon :(
jonkeller fcad58a
Addresses review feedback
jonkeller 4c52b48
Splits crossDomainIframe functionality out from transport.js into ifr…
jonkeller 2920068
Removes a couple blank lines
jonkeller d5b2dae
Fixes merge conflict
jonkeller 7b12404
Mostly changes comments, removes a small amount of redundant unit tes…
jonkeller 28c7b7a
Changes enum to const since all but one enum value no longer used. Re…
jonkeller 409ac7c
Renames things using 3P in name, changes wire format from map to array
jonkeller ee822cf
Renamed files/classes to get rid of '3p'
jonkeller f4f5048
Adds 3p iframe to amp analytics. Uses Subscription API. Event message…
jonkeller 0203122
Implements review feedback
jonkeller bff17d9
Removes extraData, new creative message
jonkeller 0d64916
Amp 3p analytics using SubscriptionAPI, 3p side
jonkeller 0e54a38
Fixes ampanalytics-lib tests
jonkeller 3d7dbd6
Fixes linter issues
jonkeller 4889860
Removes extraData, new creative message
jonkeller 21d272f
Stash
jonkeller f363bf1
Changes creative ID to transport ID
jonkeller 284d363
Includes transport ID in example logging, response
jonkeller c7898d7
Makes example ad click URL match parent branch
jonkeller 352f1f8
Addresses review feedback
jonkeller 904148d
Addresses further review feedback
jonkeller 56cc6a6
extensions/amp-analytics/0.1/amp-analytics.js
jonkeller 2cccfc3
Corrects rebase issue
jonkeller cfa8c33
Add XSS check to example HTML
jonkeller d8dde0f
Changes XSS message from log to warning
jonkeller 98249eb
Addresses review nits
jonkeller 78098c5
Addresses review feedback including removing response temporarily
jonkeller fa9c3f3
Clean up unit tests, rename event datatype
jonkeller ac5bdca
Resolves rebase issue
jonkeller d96b644
Intentionally adding trivial change, will remove in a minute
jonkeller 0f03774
Removing trival change added a minute ago. This is because Git UI is …
jonkeller 3ff0ae4
Changes an enum to a const, since all but one enum value have been re…
jonkeller 3092770
Renames things using 3P in name, changes wire format from map to array
jonkeller ac08ff3
Fixes unit test
jonkeller 8e4a0a3
Renamed files/classes to get rid of '3p'
jonkeller 29e94e5
Fixes some merge issues
jonkeller ab3db5f
Found typo in method name, which led to renaming that and a few other…
jonkeller a7f05ea
Adds missing space in error msg
jonkeller 2f9bec5
Addresses review feedback re: renaming files/class, and object field …
jonkeller 66d0cc4
Switch to IframeMessagingClient, add clarifying comment
jonkeller 545ac7b
Now uses IframeMessagingClient
jonkeller c7b6c88
Greatly simplified iframe-transport-client
jonkeller 88b6c4c
Updates unit tests
jonkeller 015c48a
Changes whitespace only
jonkeller ef8fb8d
Fixes a broken unit test
jonkeller e7c0311
Changes comment only
jonkeller 6ca88ee
Makes lib architecture more similar to ampcontext
jonkeller 1e8595d
Adds 3p/iframe-transport-client-lib.js
jonkeller 3349b6b
Differentiates message name, fixes possible null exception
jonkeller bd9a9eb
Trivial change to re-run Percy, which was flakey last time
jonkeller 39164c5
Splits request/response message types better
jonkeller 7b0a03b
Moves message type declarations into 3p-frame-messaging.js
jonkeller d265980
Addresses a few nits
jonkeller File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
/** | ||
* Copyright 2017 The AMP HTML Authors. All Rights Reserved. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS-IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
import './polyfills'; | ||
import {IframeTransportClient} from './iframe-transport-client.js'; | ||
import {initLogConstructor, setReportError} from '../src/log'; | ||
|
||
initLogConstructor(); | ||
// TODO(alanorozco): Refactor src/error.reportError so it does not contain big | ||
// transitive dependencies and can be included here. | ||
setReportError(() => {}); | ||
|
||
/** | ||
* If window.iframeTransportClient does not exist, we must instantiate and | ||
* assign it to window.iframeTransportClient, to provide the creative with | ||
* all the required functionality. | ||
*/ | ||
try { | ||
const iframeTransportClientCreated = | ||
new Event('amp-iframeTransportClientCreated'); | ||
window.iframeTransportClient = new IframeTransportClient(window); | ||
window.dispatchEvent(iframeTransportClientCreated); | ||
} catch (err) { | ||
// do nothing with error | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
/** | ||
* Copyright 2017 The AMP HTML Authors. All Rights Reserved. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS-IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
import {tryParseJson} from '../src/json'; | ||
import {dev, user} from '../src/log'; | ||
import {MessageType} from '../src/3p-frame-messaging'; | ||
import {IframeMessagingClient} from './iframe-messaging-client'; | ||
|
||
/** @private @const {string} */ | ||
const TAG_ = 'iframe-transport-client'; | ||
|
||
/** | ||
* Receives event messages bound for this cross-domain iframe, from all | ||
* creatives | ||
*/ | ||
export class IframeTransportClient { | ||
|
||
/** @param {!Window} win */ | ||
constructor(win) { | ||
/** @private {!Window} */ | ||
this.win_ = win; | ||
|
||
/** @private {?function(string,string)} */ | ||
this.listener_ = null; | ||
|
||
/** @protected {!IframeMessagingClient} */ | ||
this.client_ = new IframeMessagingClient(win); | ||
this.client_.setHostWindow(this.win_.parent); | ||
this.client_.setSentinel(user().assertString( | ||
tryParseJson(this.win_.name)['sentinel'], | ||
'Invalid/missing sentinel on iframe name attribute' + this.win_.name)); | ||
this.client_.makeRequest( | ||
MessageType.SEND_IFRAME_TRANSPORT_EVENTS, | ||
MessageType.IFRAME_TRANSPORT_EVENTS, | ||
eventData => { | ||
const events = | ||
/** | ||
* @type | ||
* {!Array<../src/3p-frame-messaging.IframeTransportEvent>} | ||
*/ | ||
(eventData['events']); | ||
user().assert(events, | ||
'Received malformed events list in ' + this.win_.location.href); | ||
dev().assert(events.length, | ||
'Received empty events list in ' + this.win_.location.href); | ||
user().assert(this.listener_, | ||
'Must call onAnalyticsEvent in ' + this.win_.location.href); | ||
events.forEach(event => { | ||
try { | ||
this.listener_ && | ||
this.listener_(event.message, event.transportId); | ||
} catch (e) { | ||
user().error(TAG_, | ||
'Exception in callback passed to onAnalyticsEvent: ' + | ||
e.message); | ||
} | ||
}); | ||
}); | ||
} | ||
|
||
/** | ||
* Registers a callback function to be called when an AMP analytics event | ||
* is received. | ||
* Note that calling this a second time will result in the first listener | ||
* being removed - the events will not be sent to both callbacks. | ||
* @param {function(string,string)} callback | ||
*/ | ||
onAnalyticsEvent(callback) { | ||
this.listener_ = callback; | ||
} | ||
|
||
/** | ||
* Gets the IframeMessagingClient | ||
* @returns {!IframeMessagingClient} | ||
* @VisibleForTesting | ||
*/ | ||
getClient() { | ||
return this.client_; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<title>Requests Frame</title> | ||
<script> | ||
window.addEventListener('amp-iframeTransportClientCreated', () => { | ||
/** | ||
* To receive AMP analytics events in a third-party frame, you must | ||
* pass a callback function to this method. The callback will be called | ||
* when an event is received, and will be passed two parameters: | ||
* @param {string} event A string of the format specified in the | ||
* requests block of the amp-analytics JSON config | ||
* @param {string} transportId An ID uniquely identifying which creative | ||
* generated the event | ||
*/ | ||
window.iframeTransportClient.onAnalyticsEvent( | ||
(event, transportId) => { | ||
// Now, do something meaningful with the AMP Analytics event | ||
console.log('The page at: ' + window.location.href + | ||
' has received an event: ' + event + | ||
' from the creative with transport ID: ' + transportId); | ||
}); | ||
}); | ||
|
||
// Load the script specified in the iframe’s name attribute: | ||
const url = JSON.parse(window.name).scriptSrc; | ||
if (url && url.startsWith('https://3p.ampproject.net/')) { | ||
script = document.createElement('script'); | ||
script.src = url; | ||
document.head.appendChild(script); | ||
// The script will be loaded, and will call onNewAmpAnalyticsInstance() | ||
} else { | ||
console.warn('Received invalid URL - risk of XSS! ' + url); | ||
} | ||
</script> | ||
</head> | ||
<!-- The frame will not be visible, so there is no need for a body tag. --> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
101 changes: 101 additions & 0 deletions
101
extensions/amp-analytics/0.1/test/test-iframe-transport-client.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
/** | ||
* Copyright 2017 The AMP HTML Authors. All Rights Reserved. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS-IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
import {MessageType} from '../../../../src/3p-frame-messaging'; | ||
import { | ||
IframeTransportClient, | ||
} from '../../../../3p/iframe-transport-client'; | ||
import {dev, user} from '../../../../src/log'; | ||
import {adopt} from '../../../../src/runtime'; | ||
import * as sinon from 'sinon'; | ||
|
||
adopt(window); | ||
|
||
let nextId = 5000; | ||
function createUniqueId() { | ||
return String(++(nextId)); | ||
} | ||
|
||
describe('iframe-transport-client', () => { | ||
let sandbox; | ||
let badAssertsCounterStub; | ||
let iframeTransportClient; | ||
let sentinel; | ||
|
||
beforeEach(() => { | ||
sandbox = sinon.sandbox.create(); | ||
badAssertsCounterStub = sandbox.stub(); | ||
sentinel = createUniqueId(); | ||
window.name = '{"sentinel": "' + sentinel + '"}'; | ||
iframeTransportClient = new IframeTransportClient(window); | ||
sandbox.stub(dev(), 'assert', (condition, msg) => { | ||
if (!condition) { | ||
badAssertsCounterStub(msg); | ||
} | ||
}); | ||
sandbox.stub(user(), 'assert', (condition, msg) => { | ||
if (!condition) { | ||
badAssertsCounterStub(msg); | ||
} | ||
}); | ||
}); | ||
|
||
afterEach(() => { | ||
sandbox.restore(); | ||
}); | ||
|
||
/** | ||
* Sends a message from the current window to itself | ||
* @param {string} type Type of the message. | ||
* @param {!JsonObject} object Message payload. | ||
*/ | ||
function send(type, data) { | ||
const object = {}; | ||
object['type'] = type; | ||
object['sentinel'] = sentinel; | ||
if (data['events']) { | ||
object['events'] = data['events']; | ||
} else { | ||
object['data'] = data; | ||
} | ||
const payload = 'amp-' + JSON.stringify(object); | ||
window./*OK*/postMessage(payload, '*'); | ||
} | ||
|
||
it('fails to create iframeTransportClient if no window.name ', () => { | ||
const oldWindowName = window.name; | ||
expect(() => { | ||
window.name = ''; | ||
new IframeTransportClient(window); | ||
}).to.throw(/Cannot read property 'sentinel' of undefined/); | ||
window.name = oldWindowName; | ||
}); | ||
|
||
it('sets sentinel from window.name.sentinel ', () => { | ||
expect(iframeTransportClient.getClient().sentinel_).to.equal(sentinel); | ||
}); | ||
|
||
it('receives an event message ', () => { | ||
window.processAmpAnalyticsEvent = (event, transportId) => { | ||
expect(transportId).to.equal('101'); | ||
expect(event).to.equal('hello, world!'); | ||
}; | ||
send(MessageType.IFRAME_TRANSPORT_EVENTS, /** @type {!JsonObject} */ ({ | ||
events: [ | ||
{transportId: '101', message: 'hello, world!'}, | ||
]})); | ||
}); | ||
}); |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Modelled after https://github.com/ampproject/amphtml/blob/ea4b3f60b0c6293d4fb31f100886b666cb1f398b/3p/ampcontext-lib.js