From 8ab0234dda20c2e266c5dea98ca0f1b6795a3189 Mon Sep 17 00:00:00 2001 From: Hongfei Ding Date: Mon, 16 Jul 2018 16:13:32 -0700 Subject: [PATCH] Support referrerPolicy:no-referrer in amp-analytics (#16734) * Support referrerPolicy:no-referrer in amp-analytics * Add test * Fix type checks. * Add documentation --- builtins/amp-pixel.js | 55 +-------------- examples/analytics.amp.html | 18 +++++ extensions/amp-analytics/0.1/transport.js | 23 ++++-- extensions/amp-analytics/amp-analytics.md | 14 ++++ src/pixel.js | 85 +++++++++++++++++++++++ test/integration/test-amp-analytics.js | 82 ++++++++++++++++++++++ 6 files changed, 217 insertions(+), 60 deletions(-) create mode 100644 src/pixel.js create mode 100644 test/integration/test-amp-analytics.js diff --git a/builtins/amp-pixel.js b/builtins/amp-pixel.js index d96b32383855..4f713b21d20b 100644 --- a/builtins/amp-pixel.js +++ b/builtins/amp-pixel.js @@ -16,11 +16,9 @@ import {BaseElement} from '../src/base-element'; import {Services} from '../src/services'; -import {createElementWithAttributes} from '../src/dom'; +import {createPixel} from '../src/pixel'; import {dev, user} from '../src/log'; -import {dict} from '../src/utils/object'; import {registerElement} from '../src/service/custom-element-registry'; -import {toWin} from '../src/types'; const TAG = 'amp-pixel'; @@ -89,9 +87,7 @@ export class AmpPixel extends BaseElement { return Services.urlReplacementsForDoc(this.element) .expandUrlAsync(this.assertSource_(src)) .then(src => { - const pixel = this.referrerPolicy_ - ? createNoReferrerPixel(this.element, src) - : createImagePixel(this.win, src); + const pixel = createPixel(this.win, src, this.referrerPolicy_); dev().info(TAG, 'pixel triggered: ', src); return pixel; }); @@ -112,53 +108,6 @@ export class AmpPixel extends BaseElement { } } -/** - * @param {!Element} parentElement - * @param {string} src - * @return {!Element} - */ -function createNoReferrerPixel(parentElement, src) { - if (isReferrerPolicySupported()) { - return createImagePixel(toWin(parentElement.ownerDocument.defaultView), src, - true); - } else { - // if "referrerPolicy" is not supported, use iframe wrapper - // to scrub the referrer. - const iframe = createElementWithAttributes( - /** @type {!Document} */ (parentElement.ownerDocument), 'iframe', dict({ - 'src': 'about:blank', - })); - parentElement.appendChild(iframe); - createImagePixel(iframe.contentWindow, src); - return iframe; - } -} - -/** - * @param {!Window} win - * @param {string} src - * @param {boolean=} noReferrer - * @return {!Image} - */ -function createImagePixel(win, src, noReferrer) { - const image = new win.Image(); - if (noReferrer) { - image.referrerPolicy = 'no-referrer'; - } - image.src = src; - return image; -} - -/** - * Check if element attribute "referrerPolicy" is supported by the browser. - * At this moment (4/14/2017), Safari does not support it yet. - * - * @return {boolean} - */ -export function isReferrerPolicySupported() { - return 'referrerPolicy' in Image.prototype; -} - /** * @param {!Window} win Destination window for the new element. */ diff --git a/examples/analytics.amp.html b/examples/analytics.amp.html index 3a22e48e4389..a7775f8d29a4 100644 --- a/examples/analytics.amp.html +++ b/examples/analytics.amp.html @@ -29,6 +29,24 @@
Container for analytics tags. Positioned far away from top to make sure that doesn't matter. + + + + + `, + extensions: ['amp-analytics'], + }, env => { + it('should keep referrer if no referrerpolicy specified', () => { + return withdrawRequest(env.win, + 'analytics-has-referrer').then(request => { + expect(request.headers.referer).to.be.ok; + }); + }); + }); + + describes.integration('amp-analytics integration test', { + body: + ` + + + `, + extensions: ['amp-analytics'], + }, env => { + it('should remove referrer if referrerpolicy=no-referrer', () => { + return withdrawRequest(env.win, 'analytics-no-referrer').then(request => { + expect(request.headers.referer).to.not.be.ok; + }); + }); + }); +});