PageSourceSearch

https://njoy.bg/box/js/njoy-ads.js?b=95

js njoy.bg collected 2026-10-02 12:53:53 UTC 8,348 bytes, 181 lines download raw bytes

1/*
2 * N-JOY ads — GPT lifecycle that survives pjax navigation.
3 *
4 * Full load : define + display every ad slot whose container is on the page.
5 * pjax nav  : in-content slots get their <div> swapped, so we destroy + redefine
6 *             + display them; the global slots (outside #njp-pjax-root) keep their
7 *             <div>, so we just refresh() them for a fresh ad on the new page.
8 *
9 * Slot ids / paths / sizes come verbatim from the client's GPT codes.
10 * ES5 only (this app's browser code is jQuery ES5).
11 */
12(function () {
13    var SLOTS = {
14        "div-gpt-ad-1781870884903-0": { path: "/120344282/njoy_top", sizes: [1, 1] },
15        "div-gpt-ad-1781870821819-0": { path: "/120344282/njoy_wallpaper", sizes: [1, 1] },
16        "div-gpt-ad-1781870127457-0": { path: "/120344282/njoy_megaboard", sizes: [[980, 300], [980, 600], [728, 90], [320, 100], [980, 200], [980, 100], [970, 250], [970, 90], [300, 250]] },
17        "div-gpt-ad-1781870621512-0": { path: "/120344282/njoy_megaboard_second", sizes: [[320, 100], [980, 200], [980, 300], [980, 600], [970, 90], [970, 250], [728, 90], [980, 100], [300, 250]] },
18        "div-gpt-ad-1781869801787-0": { path: "/120344282/njoy_medium_rectangle_300x250_first", sizes: [[300, 600], [300, 250], [300, 100], [300, 75], [300, 50]] },
19        "div-gpt-ad-1781869898977-0": { path: "/120344282/njoy_medium_rectangle_300x250_first", sizes: [[300, 250], [300, 100], [300, 75], [300, 50]] },
20        "div-gpt-ad-1781870007844-0": { path: "/120344282/njoy_medium_rectangle_300x250_second", sizes: [[300, 600], [300, 250], [300, 100], [300, 75], [300, 50]] },
21        "div-gpt-ad-1781870039284-0": { path: "/120344282/njoy_medium_rectangle_300x250_second", sizes: [[300, 250], [300, 100], [300, 75], [300, 50]] },
22        "div-gpt-ad-1781870672189-0": { path: "/120344282/njoy_carousel", sizes: [1, 1] }
23    };
24
25    // Megaboards carry sizes up to 980px wide. Without a size map, GPT could serve
26    // a 980px creative on a phone and blow out the layout. Restrict by viewport so
27    // mobile only ever gets mobile-width sizes.
28    var MEGABOARDS = {
29        "div-gpt-ad-1781870127457-0": 1,
30        "div-gpt-ad-1781870621512-0": 1
31    };
32    // Transition interstitial — show once per full load, skip on pjax (don't re-fire per click).
33    var TOP_SLOT = "div-gpt-ad-1781870884903-0";
34    var megaMap = null;
35    function megaboardMap() {
36        if (megaMap) { return megaMap; }
37        megaMap = googletag.sizeMapping()
38            .addSize([1024, 0], [[980, 600], [980, 300], [980, 200], [980, 100], [970, 250], [970, 90], [728, 90]])
39            .addSize([728, 0], [[728, 90], [320, 100]])
40            .addSize([0, 0], [[300, 250], [320, 100], [320, 50]])
41            .build();
42        return megaMap;
43    }
44
45    window.googletag = window.googletag || { cmd: [] };
46    var servicesEnabled = false;
47
48    function present(id) { return !!document.getElementById(id); }
49
50    function presentIds() {
51        var out = [], id;
52        for (id in SLOTS) {
53            if (SLOTS.hasOwnProperty(id) && present(id)) { out.push(id); }
54        }
55        return out;
56    }
57
58    function definedById() {
59        var map = {};
60        try {
61            var slots = googletag.pubads().getSlots();
62            for (var i = 0; i < slots.length; i++) {
63                map[slots[i].getSlotElementId()] = slots[i];
64            }
65        } catch (e) {}
66        return map;
67    }
68
69    function targeting() {
70        var root = document.getElementById("njp-pjax-root");
71        var aid = (root && root.getAttribute("data-njoy-article")) || "0";
72        var sid = (root && root.getAttribute("data-njoy-section")) || "160792091";
73        return { article_id: aid, section_id: sid };
74    }
75
76    function applyTargeting() {
77        try {
78            var t = targeting();
79            var template = "unknown";
80            if (location.pathname === "/") { template = "homepage"; }
81            else if (t.article_id && t.article_id !== "0") { template = "article"; }
82            else if (t.section_id && t.section_id !== "0") { template = "section"; }
83            googletag.pubads().setTargeting("template", template);
84            googletag.pubads().setTargeting("article_id", t.article_id || "0");
85            googletag.pubads().setTargeting("section_id", t.section_id || "");
86        } catch (e) {}
87    }
88
89    // Inner pages: the first megaboard belongs INSIDE the white content, right after the
90    // page title — never in the orange hero seam. The homepage places it in its template
91    // (after the live panel), so this only inserts when the div isn't already on the page.
92    function ensureMegaboardPlacement() {
93        var id = "div-gpt-ad-1781870127457-0";
94        if (document.getElementById(id)) { return; }
95        var title = document.querySelector("#njp-pjax-root .big-section-title");
96        if (!title || !title.parentNode) { return; }
97        var wrap = document.createElement("div");
98        wrap.className = "njoy-ad njoy-ad--megaboard-first";
99        wrap.innerHTML = "<!-- SMART START: njoy_megaboard - inner page, between breadcrumb and title -->"
100            + "<div id='" + id + "' style='min-width:320px;min-height:90px;'></div>"
101            + "<!-- SMART END: njoy_megaboard -->";
102        title.parentNode.insertBefore(wrap, title);
103    }
104
105    function defineIfNeeded(id, defined) {
106        if (defined[id]) { return true; }
107        var cfg = SLOTS[id];
108        var slot = googletag.defineSlot(cfg.path, cfg.sizes, id);
109        if (!slot) { return false; }
110        if (MEGABOARDS[id]) { slot.defineSizeMapping(megaboardMap()); }
111        slot.addService(googletag.pubads());
112        return true;
113    }
114
115    // Debug aid (visible only with ads ON, i.e. to the team): flag empty slots so every
116    // position is visible. A dashed placeholder = the slot IS placed/displayed and the blank
117    // is GAM returning no ad for that unit, NOT a code problem.
118    function onSlotRender(event) {
119        var el = document.getElementById(event.slot.getSlotElementId());
120        var wrap = el && el.parentNode ? el.parentNode : null;
121        if (!wrap || wrap.nodeType !== 1) { return; }
122        if (event.isEmpty) {
123            wrap.setAttribute("data-njoy-empty", event.slot.getAdUnitPath().split("/").pop());
124        } else {
125            wrap.removeAttribute("data-njoy-empty");
126        }
127    }
128
129    function initialLoad() {
130        googletag.cmd.push(function () {
131            ensureMegaboardPlacement();
132            var defined = definedById();
133            var ids = presentIds(), i;
134            for (i = 0; i < ids.length; i++) { defineIfNeeded(ids[i], defined); }
135
136            applyTargeting();
137            if (!servicesEnabled) {
138                googletag.pubads().enableSingleRequest();
139                googletag.pubads().collapseEmptyDivs();
140                googletag.pubads().addEventListener("slotRenderEnded", onSlotRender);
141                googletag.enableServices();
142                servicesEnabled = true;
143            }
144
145            for (i = 0; i < ids.length; i++) { googletag.display(ids[i]); }
146        });
147    }
148
149    function onPjax() {
150        googletag.cmd.push(function () {
151            applyTargeting();
152            ensureMegaboardPlacement();
153
154            // Destroy every defined slot except the interstitial, then redefine + display
155            // every slot present on the new page. Uniform handling also covers slots that are
156            // global on most pages but in-content on the homepage (the first megaboard).
157            var defined = definedById(), id, destroy = [];
158            for (id in defined) {
159                if (defined.hasOwnProperty(id) && id !== TOP_SLOT) { destroy.push(defined[id]); }
160            }
161            if (destroy.length) { googletag.destroySlots(destroy); }
162
163            var ids = presentIds(), i, show = [];
164            for (i = 0; i < ids.length; i++) {
165                if (ids[i] === TOP_SLOT) { continue; }
166                if (defineIfNeeded(ids[i], {})) { show.push(ids[i]); }
167            }
168            for (i = 0; i < show.length; i++) { googletag.display(show[i]); }
169        });
170    }
171
172    if (window.jQuery) {
173        jQuery(document).on("njp:pjax:loaded", onPjax);
174    }
175
176    if (document.readyState === "loading") {
177        document.addEventListener("DOMContentLoaded", initialLoad);
178    } else {
179        initialLoad();
180    }
181})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.