Skip to content

Instantly share code, notes, and snippets.

@grobertson
Created August 19, 2015 23:01
Show Gist options
  • Save grobertson/b6f5461b6491c49d7186 to your computer and use it in GitHub Desktop.
Save grobertson/b6f5461b6491c49d7186 to your computer and use it in GitHub Desktop.
//create namespace
var googletag = googletag || {};
googletag.cmd = googletag.cmd || [];
var dot = dot || {};
dot.native = dot.native || {};
dot.native.ads = dot.native.ads || {};
//Just configurations. These plaements may or may not exist
dot.native.ads._placements = {};
//Initialized "slots"
dot.native.ads._adSlots = {};
//Slots to be displayed
dot.native.ads._displayAdSlots = [];
dot.native.ads._lazyLoadAdSlots = [];
googletag.pubads().disableInitialLoad();
googletag.pubads().enableSingleRequest();
googletag.enableServices();
//Takes the configuration as an argument
dot.native.ads.prototype.configure = function(adDataConfig) {
this._placements = adDataConfig.placements;
this.setTargeting(adDataConfig.dfpAccount, adDataConfig.targeting);
this.masterSlot = adDataConfig.masterSlot || null;
};
dot.native.ads.prototype.setTargeting = function(dfpAccount, targetings) {
this.dfpAdUnit_ = [dfpAccount.account,
dfpAccount.network,
dfpAccount.sitename];
if(dfpAccount.section) {
this.dfpAdUnit_.push(dfpAccount.section);
}
var targetingKeys = Object.keys(targetings);
for(target in targetings){
// This should enumerate each item in targetings and call setTargeting(Key, Value)
googletag.pubads().setTargeting(targetingKeys[target], targetings[target]);
}
};
/**
* Finds any elements that in the dom or in opt_element that need to be
* initalized as with googletab.
*
* The element if passed is used as a scope within which to search.
*/
dot.native.ads.prototype.discover = function(opt_element) {
var initialLoadAdSlots = [];
var elements = this.findElements_(opt_element || null);
for (var i = 0; i < elements.length; i++) {
var element = elements[i].element;
try {
elements[i].dfpAdSlot = this.defineSlot_(elements[i].slug, elements[i].id));
googletag.pubads().refresh(elements[i].dfpAdSlot);
} catch (error) {
//do nothing
}
}
googletag.pubads().refresh(initialLoadAdSlots);
};
dot.native.ads.prototype.findElements_ = function(opt_element) {
var placements = this._placements;
var adElements = [];
if(this.masterSlot != null){
//To register master/companion ad units correctly we'll
//handle the adplacement defined in configuration as the master
//here first, removing it from our clone of the placements map.
for (placement in placements) {
if(this.masterSlot == placements[placement].slug){
var elements = document.getElementsByClassName(placements[placement].slug);
//There should only ever be one master placement but, to be safe..
for (element in elements) {
var id = 'ad-' + Math.floor(Math.random() * 1000000000000);
elements[element].id = id; // gives this class only element a unique id.
adElements.push({ "element": elements[element], "slug": placements[placement].slug, "id": id});
}
}
//Now do the remaining non-masterSlot slugs
if(this.masterSlot != placements[placement].slug){
var elements = document.getElementsByClassName(placements[placement].slug);
//There should only ever be one master placement but, to be safe..
for (element in elements) {
var id = 'ad-' + Math.floor(Math.random() * 1000000000000);
elements[element].id = id; // gives this class only element a unique id.
adElements.push({ "element": elements[element], "slug": placements[placement].slug, "id": id});
}
}
}
// Elements are initialized in the order returned.
return adElements;
};
// Above here should mostly work. Below here is yet to be translated but, are methods I'll likely keep.
dot.native.ads.defineAdUnit = function(adUnit, sizes) {
this._adUnits[this._convertAdSizesToKey(sizes)] = adUnit;
};
dot.native.ads.defineAdSlots = function() {
while (this._defineAdSlots.length > 0) {
var id = this._defineAdSlots.shift();
var slot = googletag.defineSlot(this._adSlots[id].adUnit, this._adSlots[id].sizes, id)
.addService(googletag.pubads())
.setTargeting('passback', 'none');
if (this._adSlots[id].targeting) {
var targeting = this._adSlots[id].targeting;
for (var key in targeting) {
slot.setTargeting('' + key, targeting[key]);
}
}
this._adSlots[id].slot = slot;
}
};
dot.native.ads._getAdSlot = function(sizes, lazy, targeting, restrictSizes) {
var id = 'ad-' + Math.floor(Math.random() * 1000000000000);
var offset = '';
if (lazy) {
offset = "data-appear-top-offset='300'"
}
this._defineAdSlots.push(id);
if (lazy) {
this._lazyLoadAdSlots.push(id);
} else {
this._displayAdSlots.push(id);
}
this._adSlots[id] = {
adUnit: this._adUnits[this._convertAdSizesToKey(sizes)],
sizes: restrictSizes != null ? restrictSizes : sizes
}
if (targeting) {
this._adSlots[id].targeting = targeting;
}
return "<div id='" + id + "' " + offset + "></div>";
}
dot.native.ads.writeAdSlot = function(sizes, lazy, targeting) {
var e = this._getAdSlot(sizes, lazy, targeting)
document.write(e);
googletag.cmd.push(function() {
dot.native.ads.defineAdSlots();
});
};
dot.native.ads.insertAdSlot = function(id, sizes, lazy, targeting, restrictSizes) {
var e = this._getAdSlot(sizes, lazy, targeting, restrictSizes)
document.getElementById(id).innerHTML = e;
googletag.cmd.push(function() {
dot.native.ads.defineAdSlots();
});
}
dot.native.ads.loadAdSlots = function() {
googletag.cmd.push(function() {
googletag.enableServices();
dot.native.ads.displayAdSlots();
});
}
dot.native.ads.displayAdSlots = function() {
while (this._displayAdSlots.length > 0) {
googletag.display(this._displayAdSlots.shift());
}
}
dot.native.ads.passback = function(iframeName, passback) {
for (var id in this._adSlots) {
var adSlot = document.getElementById(id);
var children = adSlot.childNodes;
for (var i = 0; i < children.length; i++) {
if (children[i].name == iframeName) {
var slot = this._adSlots[adSlot.id].slot;
console.log('Refreshing ' + iframeName + ' with passback ' + passback);
slot.setTargeting('passback', passback);
googletag.enableServices();
googletag.pubads().refresh(slot);
}
}
}
}
//Should take one of the placements.adSizeRanges as argument
// and return a csv list of sizes
// FGR NOT SURE IF THIS NEEDS HEIGHT? DFP doc unclear
dot.native.ads._convertAdSizesToKey = function(sizes) {
var key = [];
for (size in sizes){
key.push([sizes[size].width, sizes[size].height]);
}
return key.toString();
}
//Example configuration
var adData = {
"placements": [{
"adSizeRanges": [{
"startWidth": 0,
"endWidth": 727,
"sizes": [{
"width": 320,
"height": 100
}, {
"width": 320,
"height": 50
}, {
"width": 300,
"height": 250
}, {
"width": 320,
"height": 150
}, {
"width": 300,
"height": 1
}]
}, {
"startWidth": 970,
"endWidth": 9999,
"sizes": [{
"width": 970,
"height": 1
}, {
"width": 1000,
"height": 220
}, {
"width": 970,
"height": 90
}, {
"width": 728,
"height": 90
}, {
"width": 970,
"height": 250
}, {
"width": 970,
"height": 220
}, {
"width": 970,
"height": 550
}]
}, {
"startWidth": 728,
"endWidth": 969,
"sizes": [{
"width": 728,
"height": 90
}, {
"width": 728,
"height": 135
}, {
"width": 728,
"height": 415
}, {
"width": 728,
"height": 1
}]
}],
"adTargetings": [],
"lazyLoadOffset": null,
"slug": "mezzanine",
"isDesktop": true,
"isTablet": true,
"isMobile": true,
"isLazyLoad": false,
"indexed": false
}, {
"adSizeRanges": [{
"startWidth": 0,
"endWidth": 727,
"sizes": [{
"width": 320,
"height": 100
}, {
"width": 320,
"height": 50
}, {
"width": 320,
"height": 150
}]
}, {
"startWidth": 970,
"endWidth": 9999,
"sizes": [{
"width": 1000,
"height": 220
}, {
"width": 970,
"height": 90
}, {
"width": 970,
"height": 66
}, {
"width": 728,
"height": 90
}, {
"width": 970,
"height": 250
}, {
"width": 970,
"height": 220
}]
}, {
"startWidth": 728,
"endWidth": 969,
"sizes": [{
"width": 728,
"height": 90
}, {
"width": 728,
"height": 135
}]
}],
"adTargetings": [{
"tKey": "key",
"tValue": "value"
}],
"lazyLoadOffset": null,
"slug": "headliner",
"isDesktop": true,
"isTablet": true,
"isMobile": true,
"isLazyLoad": false,
"indexed": false
}, {
"adSizeRanges": [{
"startWidth": 0,
"endWidth": 727,
"sizes": [{
"width": 320,
"height": 100
}, {
"width": 320,
"height": 50
}, {
"width": 300,
"height": 250
}, {
"width": 320,
"height": 150
}]
}, {
"startWidth": 728,
"endWidth": 969,
"sizes": [{
"width": 728,
"height": 90
}, {
"width": 728,
"height": 135
}]
}, {
"startWidth": 970,
"endWidth": 9999,
"sizes": [{
"width": 1000,
"height": 220
}, {
"width": 970,
"height": 90
}, {
"width": 728,
"height": 90
}, {
"width": 970,
"height": 220
}, {
"width": 970,
"height": 250
}]
}],
"adTargetings": [],
"lazyLoadOffset": null,
"slug": "intermission",
"isDesktop": true,
"isTablet": true,
"isMobile": true,
"isLazyLoad": false,
"indexed": false
}, {
"adSizeRanges": [{
"startWidth": 0,
"endWidth": 727,
"sizes": [{
"width": 320,
"height": 50
}]
}, {
"startWidth": 728,
"endWidth": 969,
"sizes": [{
"width": 300,
"height": 250
}]
}, {
"startWidth": 970,
"endWidth": 9999,
"sizes": [{
"width": 300,
"height": 250
}]
}],
"adTargetings": [],
"lazyLoadOffset": null,
"slug": "video-companion",
"isDesktop": true,
"isTablet": true,
"isMobile": true,
"isLazyLoad": true,
"indexed": false
}, {
"adSizeRanges": [{
"startWidth": 0,
"endWidth": 9999,
"sizes": [{
"width": 200,
"height": 48
}]
}],
"adTargetings": [],
"lazyLoadOffset": null,
"slug": "section-sponsorship-esports",
"isDesktop": true,
"isTablet": true,
"isMobile": true,
"isLazyLoad": false,
"indexed": false
}],
"masterSlot": "headliner",
"dfpAccount": {
"network": "DAILYDOTMEDIA",
"account": "10721840",
"sitename": "DAILYDOT"
},
"targeting": {
"page_type": "front",
"permalink": "http://www.dailydot.com/"
}
}
//Not actually sure if/how these are used. Commenting them out for now.
/*
dot.native.ads._resize_fullpage_ad = function() {
var h = $(window).height() - 55;
$("#ad-container-fullpage div iframe").height(h);
}
dot.native.ads.fullpageAd = function() {
var c = $('#ad-container-fullpage');
c.removeClass('ads-inline');
c.addClass('ads-fullpage');
this._resize_fullpage_ad();
$(window).resize(this._resize_fullpage_ad);
}*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment