src/core/ads/ad_manager.js
import $ from "jquery";
import AdSizes from "./ad_sizes";
import AdUnit from "./ad_unit";
import CookieUtil from "../cookie_util";
import "jquery.dfp";
import publish from "../decorators/publish";
import subscribe from "../decorators/subscribe";
import track from "../decorators/track";
export default class AdManager {
constructor(config) {
this.defaultConfig = {
adunits: ".adunit",
sizeMapping: AdSizes,
layers: [ "LonelyPlanet.com" ],
theme: "",
template: "",
topic: "",
adThm: "",
adTnm: "",
continent: "",
country: "",
destination: "",
city: ""
};
this.config = $.extend({}, this.defaultConfig, config);
this.adCallbacks = {
"1x1": "_superzone"
};
this.subscribe();
return this;
}
_superzone($unit) {
$unit.removeClass("adunit--leaderboard")
.addClass("adunit--superzone");
}
initialize() {
this.pluginConfig = {
dfpID: this.getNetworkID(),
setTargeting: this.formatKeywords(this.config),
namespace: this.config.layers.join("/"),
sizeMapping: this.config.sizeMapping,
enableSingleRequest: false,
collapseEmptyDivs: true,
afterEachAdLoaded: ($adunit, event) => {
this._adCallback.call(this, $adunit, event);
this._afterEachAdLoaded($adunit);
}
};
this.load();
return this;
}
@publish("ad.loaded", "ads")
_afterEachAdLoaded($adunit) {
return {
id: $adunit.attr("id"),
size: $adunit.data("sizeMapping")
};
}
@subscribe("reload", "ads")
_reload() {
this.pluginConfig.setTargeting = this.formatKeywords(window.lp.ads);
this.load();
}
_slugify(string) {
if (!string) return "";
return string.toLowerCase().replace(" ", "-");
}
_adCallback($adunit, event) {
let unit = $adunit.data("adUnit"),
currentUnit;
if (!unit) {
currentUnit = new AdUnit($adunit);
$adunit.data("adUnit", currentUnit);
}
if (!currentUnit.isEmpty()) {
this._track($adunit);
}
if (event.size) {
let callback = this.adCallbacks[event.size.join("x")];
callback && this[callback] && this[callback]($adunit, event);
}
}
@track("article ad impression load");
_track($adunit) {
return `${$adunit.data("sizeMapping")}-${$adunit[0].id}-${$adunit.data("adType") || "default"}`;
}
formatKeywords(config) {
let keywords = {
theme: config.theme,
template: config.template,
topic: config.topic,
thm: config.adThm,
ctt: this._slugify(config.continent),
continent: this._slugify(config.continent),
cnty: this._slugify(config.country),
country: this._slugify(config.country),
city: this._slugify(config.city),
dest: this._slugify(config.destination),
destination: this._slugify(config.destination),
state: this._slugify(config.state),
interest: config.interest
};
if (window.Krux) {
keywords.ksg = window.Krux.segments || "";
keywords.kuid = window.Krux.user || "";
}
if (config.tnm) {
keywords.tnm = config.tnm.replace(/\s/, "").split(",");
}
if (config.keyValues && !$.isEmptyObject(config.keyValues)) {
for (let key in config.keyValues) {
if (config.keyValues.hasOwnProperty(key)) {
keywords[key] = config.keyValues[key];
}
}
}
return keywords;
}
getNetworkID() {
let networkID = 9885583,
cookie = this._networkCookie(),
param = this._networkParam();
if (param) {
networkID = param;
} else if (cookie) {
networkID = cookie;
}
return networkID;
}
_networkCookie() {
return new CookieUtil().getCookie("lpNetworkCode");
}
_networkParam() {
let props = window.location.search.match(/lpNetworkCode=([0-9]{4,8})/);
return props ? props.pop() : null;
}
load() {
this.$adunits = $(this.config.adunits);
// Filter out ad units that have already been loaded then
// ad dimensions that may be too large for their context
this.$adunits
.filter((index) => {
return this.$adunits.eq(index).data("googleAdUnit") === undefined;
})
.dfp(this.pluginConfig);
}
@subscribe("refresh", "ads")
refresh(data) {
let i, len, unit;
if (!data) {
return window.googletag.pubads().refresh();
}
for (i = 0, len = this.$adunits.length; i < len; i++) {
if (unit = this.$adunits.eq(i).data("adUnit")) {
if (!data.type || data.type === unit.getType()) {
unit.refresh(data.ads);
}
}
}
}
}