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

MANTIS bidder: support tracking viewability of ad #2696

Merged
merged 2 commits into from
Jun 9, 2018
Merged
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
117 changes: 107 additions & 10 deletions modules/mantisBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@ function inIframe() {
return true;
}
}

function pixel(url, parent) {
var img = document.createElement('img');
img.src = url;
img.style.cssText = 'display:none !important;';
(parent || document.body).appendChild(img);
}
function isDesktop(ignoreTouch) {
var supportsTouch = !ignoreTouch && ('ontouchstart' in window || navigator.msMaxTouchPoints);
if (inIframe()) {
Expand All @@ -16,7 +21,72 @@ function isDesktop(ignoreTouch) {
var width = window.innerWidth || window.document.documentElement.clientWidth || window.document.body.clientWidth;
return !supportsTouch && (!width || width >= (window.mantis_breakpoint || 768));
}

function onVisible(element, doOnVisible, time, pct) {
var started = null;
var notified = false;
var onNotVisible = null;
var whenNotVisible = function () {
if (notified && onNotVisible) {
onNotVisible();
}
notified = false;
};
var interval;
var listener;
var doCheck = function (winWidth, winHeight, rect) {
var hidden = typeof document.hidden !== 'undefined' && document.hidden;
if (rect.width == 0 || rect.height == 0 || hidden) {
return whenNotVisible();
}
var minHeight = (rect.height * pct);
var minWidth = (rect.width * pct);
var inView = (
(
(rect.top < 0 && rect.bottom >= minHeight) ||
(rect.top > 0 && (winHeight - rect.top) >= minHeight)
) &&
(
(rect.left < 0 && rect.right >= minWidth) ||
(rect.left > 0 && (winWidth - rect.left) >= minWidth)
)
);
if (!inView) {
return whenNotVisible();
}
if (!started && time) {
started = Date.now();
return whenNotVisible();
}
if (time && Date.now() - started < time) {
return whenNotVisible();
}
if (notified) {
return;
}
doOnVisible(function (ack) {
if (ack) {
notified = true;
} else {
interval && clearInterval(interval);
listener && listener();
}
}, function (onHidden) {
onNotVisible = onHidden;
});
};
if (isAmp()) {
listener = window.context.observeIntersection(function (changes) {
changes.forEach(function (change) {
doCheck(change.rootBounds.width, change.rootBounds.height, change.boundingClientRect);
});
});
}
interval = setInterval(function () {
var winHeight = (window.innerHeight || document.documentElement.clientHeight);
var winWidth = (window.innerWidth || document.documentElement.clientWidth);
doCheck(winWidth, winHeight, element.getBoundingClientRect());
}, 100);
}
function storeUuid(uuid) {
if (window.mantis_uuid) {
return false;
Expand All @@ -30,6 +100,13 @@ function storeUuid(uuid) {
}
}

function onMessage(type, callback) {
window.addEventListener('message', function (event) {
if (event.data.mantis && event.data.type == type) {
callback(event.data.data);
}
}, false);
}
function isSendable(val) {
if (val === null || val === undefined) {
return false;
Expand All @@ -42,19 +119,15 @@ function isSendable(val) {
}
return true;
}

function isObject(value) {
return Object.prototype.toString.call(value) === '[object Object]';
}

function isAmp() {
return typeof window.context === 'object' && (window.context.tagName === 'AMP-AD' || window.context.tagName === 'AMP-EMBED');
}

function isSecure() {
return document.location.protocol === 'https:';
}

function isArray(value) {
return Object.prototype.toString.call(value) === '[object Array]';
}
Expand Down Expand Up @@ -94,7 +167,8 @@ function buildMantisUrl(path, data, domain) {
referrer: document.referrer,
tz: new Date().getTimezoneOffset(),
buster: new Date().getTime(),
secure: isSecure()
secure: isSecure(),
version: 8
};
if (!inIframe() || isAmp()) {
params.mobile = !isAmp() && isDesktop(true) ? 'false' : 'true';
Expand Down Expand Up @@ -151,6 +225,7 @@ const spec = {
}
});
const query = {
measurable: true,
bids: validBidRequests.map(function (bid) {
return {
bidId: bid.bidId,
Expand All @@ -160,8 +235,7 @@ const spec = {
})
};
}),
property: property,
version: 2
property: property
};
return {
method: 'GET',
Expand Down Expand Up @@ -200,7 +274,30 @@ const spec = {
}
}
};
onMessage('iframe', function (data) {
if (window.$sf) {
var viewed = false;
$sf.ext.register(data.width, data.height, function () {
if ($sf.ext.inViewPercentage() < 50 || viewed) {
return;
}
viewed = true;
pixel(data.pixel);
});
} else {
var frames = document.getElementsByTagName('iframe');
for (var i = 0; i < frames.length; i++) {
var frame = frames[i];
if (frame.name == data.frame) {
onVisible(frame, function (stop) {
pixel(data.pixel);
stop();
}, 1000, 0.50);
}
}
}
});

export {spec};
export { spec };

registerBidder(spec);