Skip to content
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

Integrate Google AdSense for Search and Adsense for Shopping (on the Custom Search Ads protocol) with AMP #6518

Merged
merged 37 commits into from
Dec 22, 2016

Conversation

megankj-zz
Copy link

@megankj-zz megankj-zz commented Dec 7, 2016

This change allows publishers to request Google AdSense for Search and AdSense for Shopping on the Custom Search Ads protocol. We introduce a new AMP ad type, called "csa".

#2659

@megankj-zz
Copy link
Author

@lannka Can you take a look at this?

@megankj-zz
Copy link
Author

@jasti FYI

Copy link

@jscud jscud left a comment

Choose a reason for hiding this comment

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

FWIW I've reviewed this code, though I'm not a project owner.

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

Thanks for the PR!

I saw some methods with a hundred lines. Could you please extract out some functions for better readability?

* @param {Object} container HTML element of the CSA container
* @param {number} height Height to resize, in pixels
*/
function resizeCsa(container, height) {
Copy link
Contributor

Choose a reason for hiding this comment

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

move private method to the bottom

Copy link
Author

Choose a reason for hiding this comment

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

done

* @param {*} backfillPageOptions AFS page options (if necessary)
* @param {*} backfillAdblockOptions AFS ad unit options (if necessary)
* @return {function(string,boolean)} The callback function
*/
Copy link
Contributor

Choose a reason for hiding this comment

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

add annotation @visibleForTesting if it's public only for testing purpose.

Copy link
Author

Choose a reason for hiding this comment

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

done

* This is needed for an iOS bug found in versions 10.0.1 and below that
* doesn't properly reflow the iframe upon orientation change.
*/
window.addEventListener('orientationchange', function() {
Copy link
Contributor

Choose a reason for hiding this comment

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

is it necessary to have this call outside your main function?

Copy link
Author

Choose a reason for hiding this comment

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

done

@megankj-zz
Copy link
Author

@lannka Any other feedback?

@jridgewell
Copy link
Contributor

ping @lannka

// Get parent width in case we want to override
const width = global.document.body.clientWidth;

validateData(data, [], ['afshPageOptions',
Copy link
Contributor

Choose a reason for hiding this comment

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

nitpick: please break line before 'afshPageOptions', and after 'ampSlotIndex'

Copy link
Author

Choose a reason for hiding this comment

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

done

afshPageOptions['source'] = 'amp';
afshPageOptions['referer'] = window.context.referrer;
} catch (e) {}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

you can leverage Object.assign

import {tryParseJson} from 'src/json.js';

const afshPageOptions = Object.assign(
    {source: 'amp', referer: global.context.referrer}, 
    tryParseJson(data['afshPageOptions']));

you might need to run gulp dep-check to see if there's dependency errors. adding json.js to the whitelist should fix that.

Copy link
Author

Choose a reason for hiding this comment

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

tryParseJson isn't gauranteed to return an Object, so gulp check-types complains when I do this

actual parameter 1 of Object.assign does not match formal parameter
found   : (*|undefined)
required: Object
    tryParseJson(data['afsPageOptions']),

* This is needed for an iOS bug found in versions 10.0.1 and below that
* doesn't properly reflow the iframe upon orientation change.
*/
window.addEventListener('orientationchange', function() {
Copy link
Contributor

Choose a reason for hiding this comment

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

use arrow function

Copy link
Author

Choose a reason for hiding this comment

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

done

// Save the height of the container before the event listener triggers
const oldHeight = document.getElementById('csacontainer').style.height;

setTimeout(function() {
Copy link
Contributor

Choose a reason for hiding this comment

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

same here

Copy link
Author

Choose a reason for hiding this comment

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

done

'ampSlotIndex']);

// Add the ad container to the document
const d = global.document.createElement('div');
Copy link
Contributor

Choose a reason for hiding this comment

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

can you give it a better name, like containerDiv?

Copy link
Author

Choose a reason for hiding this comment

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

done

* @param {Node} container HTML element of the CSA container
* @param {number} containerH Height to resize the CSA container, in pixels
*/
function createOverflow(overflowH, fullH, container, containerH) {
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: please swap the position of createOverFlow and resizeCsa. Easier for reader to follow the logic.

Copy link
Author

Choose a reason for hiding this comment

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

done

global._googCsa('plas', afshPageOptions, afshAdblockOptions);
}
});

Copy link
Contributor

Choose a reason for hiding this comment

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

remove

Copy link
Author

Choose a reason for hiding this comment

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

Why do you want me to remove this? This is an ad call.

Copy link
Contributor

Choose a reason for hiding this comment

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

i meant remove the blank line :-)

* @return {function(string,boolean)} The callback function
* @visibleForTesting
*/
export function generateCallback(backfillPageOptions, backfillAdblockOptions) {
Copy link
Contributor

Choose a reason for hiding this comment

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

you will want to pass in the global object

Copy link
Author

Choose a reason for hiding this comment

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

done


/**
* Create a callback function to resize the iframe and/or request backfill
* @param {*} backfillPageOptions AFS page options (if necessary)
Copy link
Contributor

Choose a reason for hiding this comment

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

{?Object}

Copy link
Author

Choose a reason for hiding this comment

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

If I annotate is as anything other than *, gulp check-types complains

found   : (*|undefined)
required: Object
    tryParseJson(data['afshPageOptions'])

* @param {string} containerName
* @param {boolean} adsLoaded
*/
const resizeIframe = function(containerName, adsLoaded) {
Copy link
Contributor

Choose a reason for hiding this comment

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

instead of return a function, we typically do:

afshAdblockOptions['adLoadedCallback'] = resizeIframe.bind(null, afsPageOptions, afsAdblockOptions);

function resizeIframe(backfillPageOptions, backfillAdblockOptions, containerName, adsLoaded) {
  ...
}

Copy link
Author

Choose a reason for hiding this comment

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

done

Copy link
Author

@megankj-zz megankj-zz left a comment

Choose a reason for hiding this comment

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

Latest round of changes are done, but this code doesn't pass check-types because JSON.parse isn't guaranteed to return an Object.

change some variable names, mostly condense code
global.innerHeight doesn't work because I need the height of the AMP
container at the time of requesting the ads before the iframe is
resized. Different browsers have different behaviors (some bust the
iframe, some don't). Changing to global.innerHeight broke the overflow
implementation on iOS.
iOS9 appears to have a race condition and sometimes shows the overflow
on top of the ads, even though ALL containers and iframe appear to have
the right height set .  Adding this to see if it fixes the issue.  This
doesn’t appear to be a problem for iOS10 or Android.
I’m adding this because on ios9, the ad content is visible underneath
the overflow element, even though the height of the container and
iframe are being set correctly.
@megankj-zz
Copy link
Author

There is some weirdness I can't explain with iOS9 (9.3.5) that shows the overflow element on top of the adblock. When I inspect it, the heights for the AMP ad, AMP iframe, CSA div, and CSA iframe are all set correctly. I tried setting overflow-y: 'hidden' in the code and that didn't fix the problem either. If I scroll down and back up, the problem fixes itself. If I play around with the CSS properties (and don't actually change anything, just set it back to what it was before) it fixes itself.

Not sure what's going on here but I'll investigate more on Monday.

@megankj-zz
Copy link
Author

On iOS9, when a resize is requested sometimes the CSA iframe busts and then returns to it's full height even though we have set the height via CSS. I was able to stop this behavior by setting the iframe width to "100%", but you can still see a flicker of the ad expanding and contracting. For some reason this only happens some of the time on iOS9 and not at all on iOS10 or Android. Perhaps this is related to the iframe reflow issue that required me to add an event listener for orientation change.

One possible way to stop the flicker is to make the overflow background a solid color and not transparent, but that locks partners into a particular styling which we probably don't want to do.

Test page:
http://ampcsa.herokuapp.com/examples/afstop.amp.min.html

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

If you had iOS9 particular bug that is hard to fix, I suggest you add a TODO and open an issue. We can get this PR in first.

});

// If resize was denied, show overflow element and resize container
global.context.onResizeDenied(function(requestedHeight) {
Copy link
Contributor

Choose a reason for hiding this comment

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

will there be a problem when resizeIframe() get called multiple times? Seems we're going to register multiple listener here, which could create multiple overflow elements?

Copy link
Author

Choose a reason for hiding this comment

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

Resize iframe is only called multiple times if the partner wants to make a new request for (AFS) ads if the first (AFSh) request didn't return anything. In this case, we won't have made an overflow or created any listeners because adsLoaded in resizeIframe will be false.

The resizeDenied and resizeSuccess functions check for existence of overflow before creating a new one and/or resizing.

Copy link
Contributor

Choose a reason for hiding this comment

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

Even though, I think logically it's better to move this logic out of the resize handler, to make sure we only register once.

const pageOptions = {source: 'amp', referer: global.context.referrer};
const adblockOptions = {container: containerId};
const afshPageOptions = Object.assign(
Object(tryParseJson(data['afshPageOptions'])), pageOptions);
Copy link
Contributor

Choose a reason for hiding this comment

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

did you try swap the argument position? That will help you get rid of Object().

Object.assign(pageOptions, tryParseJson(data['afshPageOptions']));

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah, never mind. that will mutate pageOptions.

Copy link
Author

Choose a reason for hiding this comment

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

Switching the order does not get rid of the check-types error. Furthermore, if a partner passes in "source" or "referrer" they would end up overriding what we set if we do it in this order.

global.addEventListener('orientationchange', () => {
// Save the height of the container before the event listener triggers
const oldHeight = containerDiv.style.height;
setTimeout(() => {
Copy link
Contributor

Choose a reason for hiding this comment

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

global.setTimeout

*/
global.addEventListener('orientationchange', () => {
// Save the height of the container before the event listener triggers
const oldHeight = containerDiv.style.height;
Copy link
Contributor

Choose a reason for hiding this comment

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

could you extract out the whole listener to a function?


// Only call for ads once the script has loaded
loadScript(global, 'https://www.google.com/adsense/search/ads.js', () => {
if (data['afsPageOptions'] != null && data['afshPageOptions'] == null) {
Copy link
Contributor

Choose a reason for hiding this comment

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

could you extract out the load callback to a function?

});

// If resize was denied, show overflow element and resize container
global.context.onResizeDenied(function(requestedHeight) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Even though, I think logically it's better to move this logic out of the resize handler, to make sure we only register once.

}

// Event listener needed for iOS9 bug
global.addEventListener('orientationchange', () => {
Copy link
Contributor

Choose a reason for hiding this comment

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

global.addEventListener('orientationchange', orientationChangeHandler.bind(null, global, containerDiv));


// Only call for ads once the script has loaded
loadScript(global, 'https://www.google.com/adsense/search/ads.js', () => {
requestCsaAds(global, data, afsPage, afsAd, afshPage, afshAd);
Copy link
Contributor

Choose a reason for hiding this comment

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

use bind here as well

let currentAmpHeight = null;

// Enum to hold different ad types
const ADTYPE = {
Copy link
Contributor

Choose a reason for hiding this comment

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

/** @enum {string} */

// Enum to hold different ad types
const ADTYPE = {
UNSUPPORTED: 0,
AFS: 1,
Copy link
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 description about the enum value?

import * as sinon from 'sinon';
import * as _3p from '../../../3p/3p';

describe('amp-ad-csa-impl', () => {
Copy link
Contributor

Choose a reason for hiding this comment

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

seems this describe wrapper can be omitted?

…resizeIframe

other minor refactoring as well
@megankj-zz
Copy link
Author

I addressed your comments and tried to remove unnecessary code to make it more compact (and in some cases fit on one line). Let me know if I should reorder the helper functions or do anything else to clean it up.

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

Some more nitpicks


/**
* Enum for different AdSense Products
* UNSUPPORTED: Value if we can't determine which product to request
Copy link
Contributor

Choose a reason for hiding this comment

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

nitpick, you can inline descriptions.

/** Value if we can't determine which product to request */
UNSUPPORTED: 0,

Object(tryParseJson(data['afsAdblockOptions'])), adblockOptions);

// Special case for AFSh when "auto" is the requested width
if (afshAd != null && afshAd['width'] == 'auto') {
Copy link
Contributor

Choose a reason for hiding this comment

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

seems afshAd is guaranteed not null

* @param {?Object} afsP The parsed AFS page options object
* @param {?Object} afsA The parsed AFS adblock options object
* @param {?Object} afshP The parsed AFSh page options object
* @param {?Object} afshA The parsed AFSh adblock options object
Copy link
Contributor

Choose a reason for hiding this comment

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

seems none of the arguments can be null

*/
function requestCsaAds(global, data, afsP, afsA, afshP, afshA) {
const type = getAdType(data);
if (type == ADTYPE.AFS) {
Copy link
Contributor

Choose a reason for hiding this comment

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

is switch more appropriate here?

* AFSHBACKFILL: AdSense for Shopping, backfilled with AdSense for Search
* @enum {number}
*/
const ADTYPE = {
Copy link
Contributor

Choose a reason for hiding this comment

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

AD_TYPE

UNSUPPORTED: 0,
AFS: 1,
AFSH: 2,
AFSHBACKFILL: 3,
Copy link
Contributor

Choose a reason for hiding this comment

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

AFSH_BACKFILL

* AFSHBACKFILL: AdSense for Shopping, backfilled with AdSense for Search
* @enum {number}
*/
const ADTYPE = {
Copy link
Contributor

Choose a reason for hiding this comment

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

can you just import this enum?

Copy link
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 with one more comment. Please also resolve merge conflicts.

global._googCsa('plas', afshP, afshA);
break;
default:
return;
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: return is not needed

* @param {boolean} ads If ads were returned or not
* @visibleForTesting
*/
export function resizeIframe(global, bkflPage, bkflAd, conName, ads) {
Copy link
Contributor

Choose a reason for hiding this comment

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

shall we just split this function into 2?

function resizeIframe(global, containerName, hasAd) {}
function backfill(global, backfillPage, backfillAd) {}

it gives not just shorter argument list, but also avoided the recursive call of resizeIframe.

Then the above listener code becomes:

afshA['adLoadedCallback'] = (containerName, hasAd) => {
  if (hasAd) {
    resizeIframe(global, containerName, hasAd);
  } else {
     backfill(global, afsP, afsA)
  }
} 

# Conflicts:
#	3p/integration.js
#	ads/_config.js
#	ads/google/adsense.md
#	examples/ads.amp.html
#	extensions/amp-ad/amp-ad.md
* @param {?Object} page Backfill AFS page options (if necessary)
* @param {?Object} adblock Backfill AFS ad unit options (if necessary)
*/
function backfillAds(global, page, adblock) {
Copy link
Contributor

Choose a reason for hiding this comment

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

this little function is only used once, you can inline.

@lannka lannka merged commit cd8cf89 into ampproject:master Dec 22, 2016
Lith pushed a commit to Lith/amphtml that referenced this pull request Dec 22, 2016
…Custom Search Ads protocol) with AMP (ampproject#6518)

* Initial commit for CSA AMP ad integration

* update ads example

* assign throwaway variable so compiler doesn't complain

* fix lint errors

* define _googCsa in backfill function

* Add link to CSA docs in AdSense docs

* fix test error

* fix type error

* feedback from jeff

* update css example

* create overflow on resize denied if it doesn't exist

* fix from jeff's comments

* initial stab at unit tests

* first stab at unit tests

* add test for backfill

* lint issues

* create helper functions and move to bottom

* hongfei's feedback

* use Object.assign and tryparsejson

* update tests

* code review changes

change some variable names, mostly condense code

* change global.innerHeight back to initial height

global.innerHeight doesn't work because I need the height of the AMP
container at the time of requesting the ads before the iframe is
resized. Different browsers have different behaviors (some bust the
iframe, some don't). Changing to global.innerHeight broke the overflow
implementation on iOS.

* force dom reflow after appending overflow

iOS9 appears to have a race condition and sometimes shows the overflow
on top of the ads, even though ALL containers and iframe appear to have
the right height set .  Adding this to see if it fixes the issue.  This
doesn’t appear to be a problem for iOS10 or Android.

* Revert "force dom reflow after appending overflow"

This reverts commit 2040f76.

* hide overflow of CSA iframe

I’m adding this because on ios9, the ad content is visible underneath
the overflow element, even though the height of the container and
iframe are being set correctly.

* Set iframe width to 100% to prevent ios9 from breaking the overflow implementation

* move code into functions

* Move resize handlers to own functions, register in CSA function, not resizeIframe

other minor refactoring as well

* nitpicks

* add forgotten breaks to switch statement

* Create two callback functions, one for backfill and one without.

* Merge remote-tracking branch 'ampproject/master' into csa-integration

# Conflicts:
#	ads/google/csa.js

* Inline backfill ads function

* Merge with adsense.md accidentally replaced HC link

* travis errors

* more travis errors
Lith pushed a commit to Lith/amphtml that referenced this pull request Dec 22, 2016
…Custom Search Ads protocol) with AMP (ampproject#6518)

* Initial commit for CSA AMP ad integration

* update ads example

* assign throwaway variable so compiler doesn't complain

* fix lint errors

* define _googCsa in backfill function

* Add link to CSA docs in AdSense docs

* fix test error

* fix type error

* feedback from jeff

* update css example

* create overflow on resize denied if it doesn't exist

* fix from jeff's comments

* initial stab at unit tests

* first stab at unit tests

* add test for backfill

* lint issues

* create helper functions and move to bottom

* hongfei's feedback

* use Object.assign and tryparsejson

* update tests

* code review changes

change some variable names, mostly condense code

* change global.innerHeight back to initial height

global.innerHeight doesn't work because I need the height of the AMP
container at the time of requesting the ads before the iframe is
resized. Different browsers have different behaviors (some bust the
iframe, some don't). Changing to global.innerHeight broke the overflow
implementation on iOS.

* force dom reflow after appending overflow

iOS9 appears to have a race condition and sometimes shows the overflow
on top of the ads, even though ALL containers and iframe appear to have
the right height set .  Adding this to see if it fixes the issue.  This
doesn’t appear to be a problem for iOS10 or Android.

* Revert "force dom reflow after appending overflow"

This reverts commit 2040f76.

* hide overflow of CSA iframe

I’m adding this because on ios9, the ad content is visible underneath
the overflow element, even though the height of the container and
iframe are being set correctly.

* Set iframe width to 100% to prevent ios9 from breaking the overflow implementation

* move code into functions

* Move resize handlers to own functions, register in CSA function, not resizeIframe

other minor refactoring as well

* nitpicks

* add forgotten breaks to switch statement

* Create two callback functions, one for backfill and one without.

* Merge remote-tracking branch 'ampproject/master' into csa-integration

# Conflicts:
#	ads/google/csa.js

* Inline backfill ads function

* Merge with adsense.md accidentally replaced HC link

* travis errors

* more travis errors
torch2424 pushed a commit to torch2424/amphtml that referenced this pull request Jan 3, 2017
…Custom Search Ads protocol) with AMP (ampproject#6518)

* Initial commit for CSA AMP ad integration

* update ads example

* assign throwaway variable so compiler doesn't complain

* fix lint errors

* define _googCsa in backfill function

* Add link to CSA docs in AdSense docs

* fix test error

* fix type error

* feedback from jeff

* update css example

* create overflow on resize denied if it doesn't exist

* fix from jeff's comments

* initial stab at unit tests

* first stab at unit tests

* add test for backfill

* lint issues

* create helper functions and move to bottom

* hongfei's feedback

* use Object.assign and tryparsejson

* update tests

* code review changes

change some variable names, mostly condense code

* change global.innerHeight back to initial height

global.innerHeight doesn't work because I need the height of the AMP
container at the time of requesting the ads before the iframe is
resized. Different browsers have different behaviors (some bust the
iframe, some don't). Changing to global.innerHeight broke the overflow
implementation on iOS.

* force dom reflow after appending overflow

iOS9 appears to have a race condition and sometimes shows the overflow
on top of the ads, even though ALL containers and iframe appear to have
the right height set .  Adding this to see if it fixes the issue.  This
doesn’t appear to be a problem for iOS10 or Android.

* Revert "force dom reflow after appending overflow"

This reverts commit 2040f76.

* hide overflow of CSA iframe

I’m adding this because on ios9, the ad content is visible underneath
the overflow element, even though the height of the container and
iframe are being set correctly.

* Set iframe width to 100% to prevent ios9 from breaking the overflow implementation

* move code into functions

* Move resize handlers to own functions, register in CSA function, not resizeIframe

other minor refactoring as well

* nitpicks

* add forgotten breaks to switch statement

* Create two callback functions, one for backfill and one without.

* Merge remote-tracking branch 'ampproject/master' into csa-integration

# Conflicts:
#	ads/google/csa.js

* Inline backfill ads function

* Merge with adsense.md accidentally replaced HC link

* travis errors

* more travis errors
jridgewell pushed a commit to jridgewell/amphtml that referenced this pull request Jan 31, 2017
…Custom Search Ads protocol) with AMP (ampproject#6518)

* Initial commit for CSA AMP ad integration

* update ads example

* assign throwaway variable so compiler doesn't complain

* fix lint errors

* define _googCsa in backfill function

* Add link to CSA docs in AdSense docs

* fix test error

* fix type error

* feedback from jeff

* update css example

* create overflow on resize denied if it doesn't exist

* fix from jeff's comments

* initial stab at unit tests

* first stab at unit tests

* add test for backfill

* lint issues

* create helper functions and move to bottom

* hongfei's feedback

* use Object.assign and tryparsejson

* update tests

* code review changes

change some variable names, mostly condense code

* change global.innerHeight back to initial height

global.innerHeight doesn't work because I need the height of the AMP
container at the time of requesting the ads before the iframe is
resized. Different browsers have different behaviors (some bust the
iframe, some don't). Changing to global.innerHeight broke the overflow
implementation on iOS.

* force dom reflow after appending overflow

iOS9 appears to have a race condition and sometimes shows the overflow
on top of the ads, even though ALL containers and iframe appear to have
the right height set .  Adding this to see if it fixes the issue.  This
doesn’t appear to be a problem for iOS10 or Android.

* Revert "force dom reflow after appending overflow"

This reverts commit 2040f76.

* hide overflow of CSA iframe

I’m adding this because on ios9, the ad content is visible underneath
the overflow element, even though the height of the container and
iframe are being set correctly.

* Set iframe width to 100% to prevent ios9 from breaking the overflow implementation

* move code into functions

* Move resize handlers to own functions, register in CSA function, not resizeIframe

other minor refactoring as well

* nitpicks

* add forgotten breaks to switch statement

* Create two callback functions, one for backfill and one without.

* Merge remote-tracking branch 'ampproject/master' into csa-integration

# Conflicts:
#	ads/google/csa.js

* Inline backfill ads function

* Merge with adsense.md accidentally replaced HC link

* travis errors

* more travis errors
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants