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

Yieldmo adapter: fix #4107, optimize #5098 #5544

Merged
merged 1 commit into from
Aug 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
190 changes: 11 additions & 179 deletions modules/yieldmoBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export const spec = {
* @param {object} bid, bid to validate
* @return boolean, true if valid, otherwise false
*/
isBidRequestValid: function(bid) {
isBidRequestValid: function (bid) {
return !!(bid && bid.adUnitCode && bid.bidId);
},
/**
Expand All @@ -25,35 +25,24 @@ export const spec = {
* @param {BidRequest[]} bidRequests A non-empty list of bid requests which should be sent to the Server.
* @return ServerRequest Info describing the request to the server.
*/
buildRequests: function(bidRequests, bidderRequest) {
buildRequests: function (bidRequests, bidderRequest) {
let serverRequest = {
p: [],
page_url: bidderRequest.refererInfo.referer,
bust: new Date().getTime().toString(),
pr: bidderRequest.refererInfo.referer,
scrd: localWindow.devicePixelRatio || 0,
dnt: getDNT(),
e: getEnvironment(),
description: getPageDescription(),
title: localWindow.document.title || '',
w: localWindow.innerWidth,
h: localWindow.innerHeight,
userConsent:
JSON.stringify({
// case of undefined, stringify will remove param
gdprApplies:
bidderRequest && bidderRequest.gdprConsent
? bidderRequest.gdprConsent.gdprApplies
: '',
cmp:
bidderRequest && bidderRequest.gdprConsent
? bidderRequest.gdprConsent.consentString
: '',
}),
us_privacy:
bidderRequest && bidderRequest.uspConsent
? bidderRequest.uspConsent
: '',
userConsent: JSON.stringify({
// case of undefined, stringify will remove param
gdprApplies: utils.deepAccess(bidderRequest, 'gdprConsent.gdprApplies') || '',
cmp: utils.deepAccess(bidderRequest, 'gdprConsent.consentString') || ''
}),
us_privacy: utils.deepAccess(bidderRequest, 'uspConsent') || ''
};

bidRequests.forEach(request => {
Expand Down Expand Up @@ -91,7 +80,7 @@ export const spec = {
* @param serverResponse successful response from Ad Server
* @return {Bid[]} an array of bids
*/
interpretResponse: function(serverResponse) {
interpretResponse: function (serverResponse) {
let bids = [];
let data = serverResponse.body;
if (data.length > 0) {
Expand All @@ -103,7 +92,7 @@ export const spec = {
}
return bids;
},
getUserSyncs: function() {
getUserSyncs: function () {
return [];
}
};
Expand Down Expand Up @@ -175,169 +164,12 @@ function getPageDescription() {
}
}

/***************************************
* Detect Environment Helper Functions
***************************************/

/**
* Represents a method for loading Yieldmo ads. Environments affect
* which formats can be loaded into the page
* Environments:
* CodeOnPage: 0, // div directly on publisher's page
* Amp: 1, // google Accelerate Mobile Pages ampproject.org
* Mraid = 2, // native loaded through the MRAID spec, without Yieldmo's SDK https://www.iab.net/media/file/IAB_MRAID_v2_FINAL.pdf
* Dfp: 4, // google doubleclick for publishers https://www.doubleclickbygoogle.com/
* DfpInAmp: 5, // AMP page containing a DFP iframe
* SafeFrame: 10,
* DfpSafeFrame: 11,Sandboxed: 16, // An iframe that can't get to the top window.
* SuperSandboxed: 89, // An iframe without allow-same-origin
* Unknown: 90, // A default sandboxed implementation delivered by EnvironmentDispatch when all positive environment checks fail
*/

/**
* Detects what environment we're in
* @returns Environment kind
*/
function getEnvironment() {
if (isSuperSandboxedIframe()) {
return 89;
} else if (isDfpInAmp()) {
return 5;
} else if (isDfp()) {
return 4;
} else if (isAmp()) {
return 1;
} else if (isDFPSafeFrame()) {
return 11;
} else if (isSafeFrame()) {
return 10;
} else if (isMraid()) {
return 2;
} else if (isCodeOnPage()) {
return 0;
} else if (isSandboxedIframe()) {
return 16;
} else {
return 90;
}
}

/**
* @returns true if we are running on the top window at dispatch time
*/
function isCodeOnPage() {
return window === window.parent;
}

/**
* @returns true if the environment is both DFP and AMP
*/
function isDfpInAmp() {
return isDfp() && isAmp();
}

/**
* @returns true if the window is in an iframe whose id and parent element id match DFP
*/
function isDfp() {
try {
const frameElement = window.frameElement;
const parentElement = window.frameElement.parentNode;
if (frameElement && parentElement) {
return (
frameElement.id.indexOf('google_ads_iframe') > -1 &&
parentElement.id.indexOf('google_ads_iframe') > -1
);
}
return false;
} catch (e) {
return false;
}
}

/**
* @returns true if there is an AMP context object
*/
function isAmp() {
try {
const ampContext = window.context || window.parent.context;
if (ampContext && ampContext.pageViewId) {
return ampContext;
}
return false;
} catch (e) {
return false;
}
}

/**
* @returns true if the environment is a SafeFrame.
*/
function isSafeFrame() {
return window.$sf && window.$sf.ext;
}

/**
* @returns true if the environment is a dfp safe frame.
*/
function isDFPSafeFrame() {
if (window.location && window.location.href) {
const href = window.location.href;
return (
isSafeFrame() &&
href.indexOf('google') !== -1 &&
href.indexOf('safeframe') !== -1
);
}
return false;
}

/**
* Return true if we are in an iframe and can't access the top window.
*/
function isSandboxedIframe() {
return window.top !== window && !window.frameElement;
}

/**
* Return true if we cannot document.write to a child iframe (this implies no allow-same-origin)
*/
function isSuperSandboxedIframe() {
const sacrificialIframe = window.document.createElement('iframe');
try {
sacrificialIframe.setAttribute('style', 'display:none');
window.document.body.appendChild(sacrificialIframe);
sacrificialIframe.contentWindow._testVar = true;
window.document.body.removeChild(sacrificialIframe);
return false;
} catch (e) {
window.document.body.removeChild(sacrificialIframe);
return true;
}
}

/**
* @returns true if the window has the attribute identifying MRAID
*/
function isMraid() {
return !!window.mraid;
}

/**
* Gets an id from the userId object if it exists
* @param {*} request
* @param {*} idType
* @returns an id if there is one, or undefined
*/
function getId(request, idType) {
let id;
if (
request &&
request.userId &&
request.userId[idType] &&
typeof request.userId === 'object'
) {
id = request.userId[idType];
}
return id;
return (typeof utils.deepAccess(request, 'userId') === 'object') ? request.userId[idType] : undefined;
}
3 changes: 2 additions & 1 deletion test/spec/modules/yieldmoBidAdapter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,12 +140,13 @@ describe('YieldmoAdapter', function () {
expect(data.hasOwnProperty('pr')).to.be.true;
expect(data.hasOwnProperty('scrd')).to.be.true;
expect(data.dnt).to.be.false;
expect(data.e).to.equal(90);
expect(data.hasOwnProperty('description')).to.be.true;
expect(data.hasOwnProperty('title')).to.be.true;
expect(data.hasOwnProperty('h')).to.be.true;
expect(data.hasOwnProperty('w')).to.be.true;
expect(data.hasOwnProperty('pubcid')).to.be.true;
expect(data.userConsent).to.equal('{"gdprApplies":"","cmp":""}');
expect(data.us_privacy).to.equal('');
});

it('should add pubcid as parameter of request', function () {
Expand Down