PageSourceSearch

https://www.fitp.it/Scripts/f_banner_news.js

js fitp.it collected 2026-09-24 19:29:20 UTC 11,556 bytes, 341 lines download raw bytes

1/* OLD */
2/* window.googletag = window.googletag || {cmd: []};
3  googletag.cmd.push(function() {
4	return;
5	// Desktop
6	if (jQueryV2(window).width() >= 768) {
7		if (jQueryV2("div[data-id=div-gpt-ad-1676889343336-0]").length){
8			googletag.defineSlot('/5196,22528140383/fit/altro/mediumrectangle_top', [300, 250], 'div-gpt-ad-1676889343336-0').addService(googletag.pubads());
9		}
10		googletag.defineSlot('/5196,22528140383/fit/altro/pushbar_top', [728, 90], 'div-gpt-ad-1676889393122-0').addService(googletag.pubads());
11	}
12	// Mobile
13	else {
14		googletag.defineSlot('/5196,22528140383/fit/mobile/altro/mobile_top', [[320, 50], [320, 100]], 'div-gpt-ad-1676889735801-0').addService(googletag.pubads());
15		if (jQueryV2("div[data-id=div-gpt-ad-1676889769331-0]").length){
16			googletag.defineSlot('/5196,22528140383/fit/mobile/altro/mediumrectangle_top', [300, 250], 'div-gpt-ad-1676889769331-0').addService(googletag.pubads());
17		}
18	}
19	googletag.pubads().enableSingleRequest();
20	googletag.pubads().collapseEmptyDivs();
21	googletag.enableServices();
22  }); */
23
24
25(function () {
26	const DEBUG = true;
27	const log = (...a) => { if (DEBUG) console.log("[ADV-BOOTSTRAP]", ...a); };
28
29	window.createAdvContentV2 = window.createAdvContentV2 || function () { return; };
30
31	const STYLE_ID = "adv-mediamond-styles";
32	const MOBILE_WRAPPER_CLASS = "adv-masthead-mobile";
33
34	const MOVER_ID = "adv-masthead-mover-js";
35	const MOVER_SRC = "/Scripts/adv-masthead-mover.js";
36
37	const MEDIAMOND_ID = "mediamond-tag-adv-v1";
38	const MEDIAMOND_SRC = "https://adv.mediamond.it/hpsponsor/fitp/tag_adv_mediamond.v1.js";
39
40	const PUSHBAR_SELECTOR = ".cc-section-news-banner-pushbar_top";
41	const CROSS_HEADER_SELECTOR = ".cc-header-cross-platform";
42
43	const CONTAINER1_ID = "adv-gpt-masthead-container1";
44	const BOX_PREFIX = "adv-gpt-box-container";
45
46	function injectStylesOnce() {
47		if (document.getElementById(STYLE_ID)) return;
48
49		const style = document.createElement("style");
50		style.id = STYLE_ID;
51		style.textContent = `
52      /* MEDIAMOND */
53      .adv-masthead { width: 100%; display: flex; justify-content: center; align-items: center; }
54      .adv-masthead-mobile, .adv-masthead-desktop { width: 100%; }
55      .adv-masthead-desktop { padding: 2rem 0rem; }
56
57      @media (min-width: 992px) {
58        .adv-masthead-mobile { display: none; }
59        .adv-masthead { justify-content: start; }
60      }
61      @media (min-width: 1400px) {
62        div#${CONTAINER1_ID} { margin-left: 0px !important; }
63      }
64      @media (max-width: 991.98px) {
65        .adv-masthead-desktop { display: none; }
66      }
67    `;
68		document.head.appendChild(style);
69		log("styles injected");
70	}
71
72	function ensureMobileWrapperBeforeCrossHeader() {
73		const crossHeader = document.querySelector(CROSS_HEADER_SELECTOR);
74		if (!crossHeader) return false;
75
76		if (document.querySelector(`.${MOBILE_WRAPPER_CLASS}`)) return true;
77
78		const wrapper = document.createElement("div");
79		wrapper.className = MOBILE_WRAPPER_CLASS;
80		wrapper.innerHTML = `<div class="adv-masthead"></div>`;
81
82		crossHeader.parentNode.insertBefore(wrapper, crossHeader);
83		log("mobile wrapper injected before cross-header");
84		return true;
85	}
86
87	function replacePushbarWithDesktopSection() {
88		const pushbar = document.querySelector(PUSHBAR_SELECTOR);
89
90		// Caso 1: pushbar presente → sostituisci
91		if (pushbar) {
92			const section = document.createElement("div");
93			section.className = "cc-section-news";
94			section.innerHTML = `
95            <div class="container">
96                <div class="row">
97                    <div class="col-md-3 col-xs-12"></div>
98                    <div class="col-md-9 col-xs-12">
99                        <div class="container">
100                            <!-- MEDIAMOND BANNER 970x250 -->
101                            <div class="adv-masthead-desktop">
102                                <div class="adv-masthead"></div>
103                            </div>
104                            <div id="${CONTAINER1_ID}"></div>
105                        </div>
106                    </div>
107                </div>
108            </div>
109        `;
110			pushbar.parentNode.replaceChild(section, pushbar);
111			log("pushbar replaced with full section structure");
112			return true;
113		}
114
115		// Caso 2: nessun pushbar, ma c'è già .adv-masthead-desktop nel DOM (template News)
116		const existingDesktop = document.querySelector(".adv-masthead-desktop");
117		if (!existingDesktop) return false;
118
119		// Già wrappato correttamente? Non fare nulla
120		if (existingDesktop.closest(".cc-section-news")) return true;
121
122		// Costruisci la struttura completa e spostaci dentro existingDesktop
123		const section = document.createElement("div");
124		section.className = "cc-section-news";
125		section.innerHTML = `
126        <div class="container">
127            <div class="row">
128                <div class="col-md-3 col-xs-12"></div>
129                <div class="col-md-9 col-xs-12">
130                    <div class="container">
131                        <!-- MEDIAMOND BANNER 970x250 -->
132                        <div class="adv-masthead-desktop-placeholder"></div>
133                        <div id="${CONTAINER1_ID}"></div>
134                    </div>
135                </div>
136            </div>
137        </div>
138    `;
139
140		// Inserisci la section prima di existingDesktop, poi spostaci il desktop dentro
141		existingDesktop.parentNode.insertBefore(section, existingDesktop);
142		const placeholder = section.querySelector(".adv-masthead-desktop-placeholder");
143		placeholder.parentNode.replaceChild(existingDesktop, placeholder);
144
145		log("existing desktop wrapped with full cc-section-news structure");
146		return true;
147	}
148
149
150	function getNextFreeBoxIndex(startAt = 1) {
151		let n = startAt;
152		while (document.getElementById(`${BOX_PREFIX}${n}`)) n++;
153		return n;
154	}
155
156	function replaceContentBannersWithContainers() {
157		const banners = Array.from(
158			document.querySelectorAll("aside.cc-content-banner, div.cc-content-banner, .cc-content-banner")
159		);
160
161		if (!banners.length) return 0;
162
163		let n = getNextFreeBoxIndex(1);
164		let replaced = 0;
165
166		for (const old of banners) {
167
168			// 🔴 NON toccare se è già un nostro banner nuovo
169			if (old.classList.contains("cc-content-banner-new")) continue;
170
171			// 🔴 NON toccare se contiene già un box container (sicurezza extra)
172			if (old.querySelector(`[id^="${BOX_PREFIX}"]`)) continue;
173
174			const wrapper = document.createElement("div");
175			wrapper.className = "cc-content-banner cc-content-banner-new";
176
177			const inner = document.createElement("div");
178			inner.id = `${BOX_PREFIX}${n}`;
179
180			wrapper.appendChild(inner);
181
182			old.parentNode.replaceChild(wrapper, old);
183
184			log("content banner replaced ->", inner.id);
185
186			replaced++;
187			n = getNextFreeBoxIndex(n + 1);
188		}
189
190		return replaced;
191	}
192
193
194	function injectExternalScriptOnce({ id, src, async = true }) {
195		if (id && document.getElementById(id)) return true;
196
197		const already = Array.from(document.scripts || []).some(
198			s => (s.src || "") === src
199		);
200		if (already) return true;
201
202		const s = document.createElement("script");
203		if (id) s.id = id;
204		s.src = src;
205		s.async = !!async;
206
207		s.onload = () => log("script loaded:", src);
208		s.onerror = () => log("script ERROR loading:", src);
209
210		// 👇 QUI LA DIFFERENZA IMPORTANTE
211		if (document.body) {
212			document.body.appendChild(s); // prima di </body>
213		} else {
214			// fallback raro
215			document.addEventListener("DOMContentLoaded", () => {
216				document.body.appendChild(s);
217			});
218		}
219
220		log("script injected at end of body:", src);
221		return true;
222	}
223
224	// --- Stabilizzazione DOM: ripete bootstrap e aspetta che la "firma" non cambi per stableMs
225	function getDomSignature() {
226		const hasM = !!document.querySelector(".adv-masthead-mobile .adv-masthead");
227		const hasD = !!document.querySelector(".adv-masthead-desktop .adv-masthead");
228		const c1 = !!document.getElementById(CONTAINER1_ID);
229		const boxes = Array.from(document.querySelectorAll(`[id^="${BOX_PREFIX}"]`)).map(e => e.id).sort().join("|");
230		return `m:${hasM ? 1 : 0}|d:${hasD ? 1 : 0}|c1:${c1 ? 1 : 0}|boxes:${boxes}`;
231	}
232
233	function bootstrapDomOnce() {
234		injectStylesOnce();
235		ensureMobileWrapperBeforeCrossHeader();
236		replacePushbarWithDesktopSection();
237		const replaced = replaceContentBannersWithContainers();
238		if (replaced) log("total content banners replaced:", replaced);
239	}
240
241	function waitForStableDom({ maxWaitMs = 9000, stableMs = 800, pollMs = 150 } = {}) {
242		return new Promise((resolve) => {
243			const start = Date.now();
244			let lastSig = null;
245			let lastChangeAt = Date.now();
246
247			const t = setInterval(() => {
248				bootstrapDomOnce();
249
250				const sig = getDomSignature();
251				const now = Date.now();
252
253				if (sig !== lastSig) {
254					lastSig = sig;
255					lastChangeAt = now;
256				}
257
258				const stableFor = now - lastChangeAt;
259				const waited = now - start;
260
261				// condizione minima: abbiamo desktop+container1 o almeno i container content
262				const hasTargets =
263					!!document.querySelector(".adv-masthead-desktop .adv-masthead") ||
264					!!document.querySelector(".adv-masthead-mobile .adv-masthead");
265
266				const hasAnyContainer =
267					!!document.getElementById(CONTAINER1_ID) ||
268					document.querySelectorAll(`[id^="${BOX_PREFIX}"]`).length > 0;
269
270				if (hasTargets && hasAnyContainer && stableFor >= stableMs) {
271					clearInterval(t);
272					resolve({ ok: true, waited, stableFor, sig });
273					return;
274				}
275
276				if (waited >= maxWaitMs) {
277					clearInterval(t);
278					resolve({ ok: false, waited, stableFor, sig });
279				}
280			}, pollMs);
281		});
282	}
283
284	// --- Mediamond: inietta SOLO dopo stabilità; retry a window.load
285	let mediamondInjected = false;
286
287	function injectMediamondNow() {
288		if (mediamondInjected) return true;
289
290		const already =
291			document.getElementById(MEDIAMOND_ID) ||
292			Array.from(document.scripts || []).some(s => (s.src || "") === MEDIAMOND_SRC);
293
294		if (already) {
295			mediamondInjected = true;
296			log("mediamond already present, skip inject");
297			return true;
298		}
299
300		const s = document.createElement("script");
301		s.id = MEDIAMOND_ID;
302		s.async = true;
303		s.src = MEDIAMOND_SRC;
304		s.onload = () => log("mediamond loaded OK");
305		s.onerror = () => log("mediamond ERROR loading", MEDIAMOND_SRC);
306
307		(document.body || document.documentElement).appendChild(s);
308		mediamondInjected = true;
309		log("mediamond injected AFTER stable DOM");
310		return true;
311	}
312
313	async function run() {
314		// (1) carica mover subito (come richiesto)
315		injectExternalScriptOnce({ id: MOVER_ID, src: MOVER_SRC, async: true });
316
317		// (2) sistema DOM + aspetta stabilità
318		const st = await waitForStableDom({ maxWaitMs: 9000, stableMs: 800, pollMs: 150 });
319		log("stable DOM result", st);
320
321		// (3) SOLO ora carica Mediamond
322		injectMediamondNow();
323	}
324
325	if (document.readyState === "loading") {
326		document.addEventListener("DOMContentLoaded", run);
327	} else {
328		run();
329	}
330
331	// Retry “ultimo” quando tutta la pagina è veramente completa.
332	// Se Mediamond fa scan in onload interno, qui è spesso la differenza tra undefined e OK.
333	window.addEventListener("load", () => {
334		// rifaccio un pass DOM (nel caso il template abbia aggiunto roba dopo)
335		bootstrapDomOnce();
336
337		// se per qualche motivo non era stato iniettato (o era stato iniettato troppo presto da altri),
338		// qui almeno garantiamo che esista.
339		injectMediamondNow();
340	});
341})();

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.