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

Mobile app rendering: if burl is missing from bid, write ad markup after MRAID-viewable #248

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
51 changes: 48 additions & 3 deletions src/mobileAndAmpRender.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,20 @@ import { writeAdHtml } from './adHtmlRender';
const DEFAULT_CACHE_HOST = 'prebid.adnxs.com';
const DEFAULT_CACHE_PATH = '/pbc/v1/cache';

/**
* Web views will have rendered and lost console.logs before the web view can be inspected
* in Safari/Chrome Dev Tools, so this will hold onto the logs in memory.
* After inspecting the web view, simply enter `pucLogs` in the dev tools console to see
* what console.logs had already taken place.
*/
function log() {
window.pucLogs = window.pucLogs || [];
window.pucLogs.push({time: new Date(), logs: [...arguments]});
if (console && console.log) {
console.log.apply(console, arguments);
}
}

/**
* Render mobile or amp ad
* @param {string} cacheHost Cache host
Expand Down Expand Up @@ -52,7 +66,7 @@ function updateIframe(size) {
const sizeArr = size.split('x').map(Number);
resizeIframe(sizeArr[0], sizeArr[1]);
} else {
console.log('Targeting key hb_size not found to resize creative');
log('Targeting key hb_size not found to resize creative');
}
}

Expand Down Expand Up @@ -131,6 +145,7 @@ function responseCallback(isMobileApp, hbPb) {
ad += createTrackPixelHtml(decodeURIComponent(bidObject.nurl));
}
if (bidObject.burl) {
log('bid has burl');
let triggerBurl = function () { triggerPixel(bidObject.burl); };
if (isMobileApp) {
let mraidScript = loadScript(window, 'mraid.js',
Expand All @@ -145,9 +160,39 @@ function responseCallback(isMobileApp, hbPb) {
} else {
triggerBurl(); // Not a mobile app
}

// Write the ad html immediately since there is a burl.
log('writing ad html immediately');
writeAdHtml(ad);
} else {
log('bid does not have burl');
let writeAdHtmlCallback = () => {
log('writing ad html from within writeAdHtmlCallback');
writeAdHtml(ad);
};
if (isMobileApp) {
log('isMobileApp - checking for mraid.js');
let mraidScript = loadScript(window, 'mraid.js',
function () { // Success loading MRAID
log('mraid.js loaded, registering writeAdHtmlCallback with mraid viewable');
let result = registerMRAIDViewableEvent(writeAdHtmlCallback);
if (!result) {
log('error registering writeAdHtmlCallback with mraid viewable, so writing ad html immediately');
writeAdHtml(ad); // Error registering event
}
},
() => {
log('error loading mraid.js, so writing ad html immediately');
writeAdHtml(ad) // Error loading MRAID
}
);
} else {
log('not mobileApp, so writing ad html immediately');
writeAdHtml(ad); // Not a mobile app
}
}
writeAdHtml(ad);
} else if (bidObject.nurl) {
log('bid did not have adm, but does have nurl');
if (isMobileApp) {
let adhtml = loadScript(window, bidObject.nurl);
ad += constructMarkup(adhtml.outerHTML, width, height);
Expand All @@ -172,7 +217,7 @@ function parseResponse(response) {
try {
bidObject = JSON.parse(response);
} catch (error) {
console.log(`Error parsing response from cache host: ${error}`);
log(`Error parsing response from cache host: ${error}`);
}
return bidObject;
}
Expand Down
91 changes: 91 additions & 0 deletions test/helpers/mraid-mocks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
export function createMraid2Mock({isReady, isViewable}) {
let _isReady = isReady || false;
let _isViewable = isViewable || false;

// Simple in that we only support 1 callback per event for test mocking purposes.
let _simpleCallbacks = {};

window.MRAID_ENV = {
version: 2
};

window.mraid = {
getState: () => _isReady ? 'ready': 'loading',
isViewable: () => _isViewable,
addEventListener: (eventName, callback) => {
_simpleCallbacks[eventName] = callback;
},
removeEventListener: (eventName) => {
if (_simpleCallbacks[eventName]) {
delete _simpleCallbacks[eventName];
}
}
};

return {
setReady(isReady) {
_isReady = isReady;
if (_simpleCallbacks.ready) {
_simpleCallbacks.ready();
}
},
setViewable(isViewable) {
_isViewable = isViewable;
if (_simpleCallbacks.viewableChange) {
_simpleCallbacks.viewableChange(_isViewable);
}
},
cleanup() {
delete window.mraid;
delete window.MRAID_ENV;
}
}
}

export function createMraid3Mock({isReady, isViewable}) {
let _isReady = isReady || false;
let _isViewable = isViewable || false;

// Simple in that we only support 1 callback per event for test mocking purposes.
let _simpleCallbacks = {};

window.MRAID_ENV = {
version: 3
};

window.mraid = {
getState: () => _isReady ? 'ready': 'loading',
isViewable: () => _isViewable,
addEventListener: (eventName, callback) => {
_simpleCallbacks[eventName] = callback;

if (eventName === 'exposureChange') {
_simpleCallbacks.exposureChange(_isViewable ? 1 : 0);
}
},
removeEventListener: (eventName) => {
if (_simpleCallbacks[eventName]) {
delete _simpleCallbacks[eventName];
}
}
};

return {
setReady(isReady) {
_isReady = isReady;
if (_simpleCallbacks.ready) {
_simpleCallbacks.ready();
}
},
setViewable(isViewable) {
_isViewable = isViewable;
if (_simpleCallbacks.exposureChange) {
_simpleCallbacks.exposureChange(_isViewable ? 1 : 0);
}
},
cleanup() {
delete window.mraid;
delete window.MRAID_ENV;
}
}
}
Loading