Source code

Revision control

Copy as Markdown

Other Tools

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
/**
* Bug 1734130 - Shim AdNexus AST
*
* Some sites expect AST to successfully load, or they break.
* This shim mitigates that breakage.
*/
if (!window.apntag?.loaded) {
const anq = window.apntag?.anq || [];
const gTags = new Map();
const gAds = new Map();
const gEventHandlers = {};
const Ad = class {
adType = "banner";
auctionId = "-";
banner = {
width: 1,
height: 1,
content: "",
trackers: {
impression_urls: [],
video_events: {},
},
};
brandCategoryId = 0;
buyerMemberId = 0;
cpm = 0.1;
cpm_publisher_currency = 0.1;
creativeId = 0;
dealId = undefined;
height = 1;
mediaSubtypeId = 1;
mediaTypeId = 1;
publisher_currency_code = "US";
source = "-";
tagId = -1;
targetId = "";
width = 1;
constructor(tagId, targetId) {
this.tagId = tagId;
this.targetId = targetId;
}
};
const fireAdEvent = (type, adObj) => {
const { targetId } = adObj;
const handlers = gEventHandlers[type]?.[targetId];
if (!handlers) {
return Promise.resolve();
}
const evt = { adObj, type };
return new Promise(done => {
setTimeout(() => {
for (const cb of handlers) {
try {
cb(evt);
} catch (e) {
console.error(e);
}
}
done();
}, 1);
});
};
const refreshTag = targetId => {
const tag = gTags.get(targetId);
if (!tag) {
return;
}
if (!gAds.has(targetId)) {
gAds.set(targetId, new Ad(tag.tagId, targetId));
}
const adObj = gAds.get(targetId);
fireAdEvent("adRequested", adObj).then(() => {
// TODO: do some sites expect adAvailable+adLoaded instead of adNoBid?
fireAdEvent("adNoBid", adObj);
});
};
const off = (type, targetId, cb) => {
gEventHandlers[type]?.[targetId]?.delete(cb);
};
const on = (type, targetId, cb) => {
gEventHandlers[type] = gEventHandlers[type] || {};
gEventHandlers[type][targetId] =
gEventHandlers[type][targetId] || new Set();
gEventHandlers[type][targetId].add(cb);
};
const Tag = class {
static #nextId = 0;
debug = undefined;
displayed = false;
initialHeight = 1;
initialWidth = 1;
keywords = {};
member = 0;
showTagCalled = false;
sizes = [];
targetId = "";
utCalled = true;
utDivId = "";
utiframeId = "";
uuid = "";
constructor(raw) {
const { keywords, sizes, targetId } = raw;
this.tagId = Tag.#nextId++;
this.keywords = keywords || {};
this.sizes = sizes || [];
this.targetId = targetId || "";
}
modifyTag() {}
off(type, cb) {
off(type, this.targetId, cb);
}
on(type, cb) {
on(type, this.targetId, cb);
}
setKeywords(kw) {
this.keywords = kw;
}
};
window.apntag = {
anq,
attachClickTrackers() {},
checkAdAvailable() {},
clearPageTargeting() {},
clearRequest() {},
collapseAd() {},
debug: false,
defineTag(dfn) {
const { targetId } = dfn;
if (!targetId) {
return;
}
gTags.set(targetId, new Tag(dfn));
},
disableDebug() {},
dongle: undefined,
emitEvent(adObj, type) {
fireAdEvent(type, adObj);
},
enableCookieSet() {},
enableDebug() {},
fireImpressionTrackers() {},
getAdMarkup: () => "",
getAdWrap() {},
getAstVersion: () => "0.49.0",
getPageTargeting() {},
getTag(targetId) {
return gTags.get(targetId);
},
handleCb() {},
handleMediationBid() {},
highlightAd() {},
loaded: true,
loadTags() {
for (const tagName of gTags.keys()) {
refreshTag(tagName);
}
},
modifyTag() {},
notify() {},
offEvent(type, target, cb) {
off(type, target, cb);
},
onEvent(type, target, cb) {
on(type, target, cb);
},
recordErrorEvent() {},
refresh() {},
registerRenderer() {},
requests: {},
resizeAd() {},
setEndpoint() {},
setKeywords() {},
setPageOpts() {},
setPageTargeting() {},
setSafeFrameConfig() {},
setSizes() {},
showTag() {},
};
const push = function (fn) {
if (typeof fn === "function") {
try {
fn();
} catch (e) {
console.trace(e);
}
}
};
anq.push = push;
anq.forEach(push);
}