diff options
Diffstat (limited to 'browser/extensions/webcompat/shims/adnexus-ast.js')
-rw-r--r-- | browser/extensions/webcompat/shims/adnexus-ast.js | 210 |
1 files changed, 210 insertions, 0 deletions
diff --git a/browser/extensions/webcompat/shims/adnexus-ast.js b/browser/extensions/webcompat/shims/adnexus-ast.js new file mode 100644 index 0000000000..ae07fa6a03 --- /dev/null +++ b/browser/extensions/webcompat/shims/adnexus-ast.js @@ -0,0 +1,210 @@ +/* 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); +} |