PageSourceSearch

https://3sitep.net/wp-content/plugins/seo3-suite/assets/frontend/banner/js/banner.js?ver=1.3.1787901935

js 3sitep.net collected 2026-10-09 22:39:51 UTC 12,580 bytes, 453 lines download raw bytes

1document.addEventListener("DOMContentLoaded", function () {
2  "use strict";
3
4  var cfg = typeof BANNERCFG !== "undefined" ? BANNERCFG : {};
5  var debug = String(cfg.debug || "0") === "1";
6  var autoBind = String(cfg.autobind || "0") === "1";
7  var apiUrl = cfg.api_url || "https://devseo4.site/wp-json/v1/banners";
8  var dataPromise = null;
9  var bindTimer = null;
10
11  function logError() {
12    if (debug && window.console) {
13      console.error.apply(console, arguments);
14    }
15  }
16
17  function logInfo() {
18    if (debug && window.console) {
19      console.log.apply(console, arguments);
20    }
21  }
22
23  function logWarn() {
24    if (debug && window.console) {
25      console.warn.apply(console, arguments);
26    }
27  }
28
29  function logResolveSource(payload) {
30    if (window.console) {
31      console.log('source: "' + (payload.source || "unknown") + '"');
32    }
33  }
34
35  function initSplide() {
36    var splides = document.querySelectorAll(".splide");
37    if (splides.length > 0 && typeof Splide !== "undefined") {
38      splides.forEach(function (el) {
39        new Splide(el, {
40          type: "loop",
41          autoplay: true,
42          perPage: 8,
43          gap: 0,
44          pagination: false,
45          arrows: false,
46          breakpoints: {
47            1024: { perPage: 6 },
48            768: { perPage: 4 },
49            480: { perPage: 3 },
50          },
51        }).mount();
52      });
53      return;
54    }
55
56    splides.forEach(function (el) {
57      el.classList.add("is-initialized");
58      el.style.visibility = "visible";
59    });
60  }
61
62  window.closeBannerBottom = function () {
63    var el = document.querySelector(".banners-bottom");
64    var openBtn = document.getElementById("open-banner-bottom");
65    if (el && openBtn) {
66      el.style.display = "none";
67      openBtn.style.display = "block";
68    }
69  };
70
71  window.openBannerBottom = function () {
72    var el = document.querySelector(".banners-bottom");
73    var openBtn = document.getElementById("open-banner-bottom");
74    if (el && openBtn) {
75      el.style.display = "block";
76      openBtn.style.display = "none";
77    }
78  };
79
80  function fetchBannerData() {
81    if (dataPromise) return dataPromise;
82
83    var separator = apiUrl.indexOf("?") === -1 ? "?" : "&";
84    var url = apiUrl + separator + "_seo4s_ts=" + Date.now();
85    logInfo("SEO4S resolve: fetching API", { url: url });
86
87    dataPromise = fetch(url, {
88      cache: "no-store",
89      headers: {
90        "Accept": "application/json",
91      },
92    })
93      .then(function (res) {
94        logInfo("SEO4S resolve: API response", {
95          status: res.status,
96          ok: res.ok,
97          url: res.url || url,
98        });
99        if (!res.ok) throw new Error("API status " + res.status);
100        return res.json();
101      })
102      .then(function (json) {
103        var data = json && json.data ? json.data : {};
104        logInfo("SEO4S resolve: API data summary", {
105          success: !!(json && json.success),
106          login_urls: Array.isArray(data.login_urls) ? data.login_urls.length : 0,
107          banners_top: Array.isArray(data.banners_top) ? data.banners_top.length : 0,
108          banners_bottom: Array.isArray(data.banners_bottom) ? data.banners_bottom.length : 0,
109          groups: data.groups && typeof data.groups === "object" ? Object.keys(data.groups).length : 0,
110        });
111        return data;
112      })
113      .catch(function (err) {
114        dataPromise = null;
115        logError("SEO4S fetch banner API failed:", err);
116        return {};
117      });
118
119    return dataPromise;
120  }
121
122  function decodeParams(encoded) {
123    if (!encoded) return "";
124    try {
125      return atob(encoded);
126    } catch (err) {
127      logError("SEO4S decode params failed:", err);
128      return "";
129    }
130  }
131
132  function encodeParams(params) {
133    try {
134      return btoa(String(params || ""));
135    } catch (err) {
136      logError("SEO4S encode params failed:", err);
137      return "";
138    }
139  }
140
141  function findItem(data, type, id) {
142    id = String(id || "").toUpperCase();
143    if (!id) return null;
144
145    var list = Array.isArray(data[type]) ? data[type] : [];
146    logInfo("SEO4S resolve: searching item", {
147      type: type,
148      id: id,
149      list_length: list.length,
150    });
151
152    for (var i = 0; i < list.length; i++) {
153      var itemId = String(list[i].id || "").toUpperCase();
154      if (itemId === id) return list[i];
155    }
156
157    return null;
158  }
159
160  function findBaseUrl(data, type, id) {
161    var item = findItem(data, type, id);
162    if (item) {
163      var primaryUrl = item.link || item.url || "";
164      logInfo("SEO4S resolve: matched primary type", {
165        type: type,
166        id: id,
167        has_url: !!primaryUrl,
168      });
169      return primaryUrl;
170    }
171
172    var fallbackTypes = ["login_urls", "banners_top", "banners_bottom"];
173    for (var i = 0; i < fallbackTypes.length; i++) {
174      if (fallbackTypes[i] === type) continue;
175
176      item = findItem(data, fallbackTypes[i], id);
177      if (item) {
178        var fallbackUrl = item.link || item.url || "";
179        logWarn("SEO4S resolve: matched live fallback type", {
180          requested_type: type,
181          matched_type: fallbackTypes[i],
182          id: id,
183          has_url: !!fallbackUrl,
184        });
185        return fallbackUrl;
186      }
187    }
188
189    logWarn("SEO4S resolve: no live API item matched", {
190      type: type,
191      id: id,
192    });
193    return "";
194  }
195
196  function findFallbackBaseUrl(type, id) {
197    var map = cfg.fallback_urls || {};
198    var key = String(id || "").toUpperCase();
199    if (!key) return "";
200
201    if (map[type] && map[type][key]) {
202      logWarn("SEO4S resolve: using cached fallback URL", {
203        type: type,
204        id: key,
205      });
206      return map[type][key];
207    }
208
209    var fallbackTypes = ["login_urls", "banners_top", "banners_bottom"];
210    for (var i = 0; i < fallbackTypes.length; i++) {
211      if (fallbackTypes[i] === type) continue;
212      if (map[fallbackTypes[i]] && map[fallbackTypes[i]][key]) {
213        logWarn("SEO4S resolve: using cached fallback URL from alternate type", {
214          requested_type: type,
215          matched_type: fallbackTypes[i],
216          id: key,
217        });
218        return map[fallbackTypes[i]][key];
219      }
220    }
221
222    logWarn("SEO4S resolve: no cached fallback URL matched", {
223      type: type,
224      id: key,
225    });
226    return "";
227  }
228
229  function buildFinalUrl(baseUrl, params) {
230    if (!baseUrl) return "";
231
232    try {
233      var url = new URL(baseUrl, window.location.href);
234      var input = String(params || "").trim();
235
236      if (input) {
237        if (/^https?:\/\//i.test(input)) {
238          input = new URL(input).search;
239        }
240        input = input.replace(/^\?/, "");
241
242        var extra = new URLSearchParams(input);
243        extra.forEach(function (value, key) {
244          url.searchParams.set(key, value);
245        });
246      }
247
248      if (window.location.hostname) {
249        url.searchParams.set("referrer_domain", window.location.hostname);
250      }
251
252      return url.toString();
253    } catch (err) {
254      logError("SEO4S build URL failed:", err);
255      return "";
256    }
257  }
258
259  function openResolvedLink(el) {
260    var type = el.getAttribute("data-type") || "login_urls";
261    var id = el.getAttribute("data-brand-id") || "";
262    var params = decodeParams(el.getAttribute("data-params") || "");
263    var target = el.getAttribute("data-target") || "_blank";
264    var pendingWindow = null;
265    logInfo("SEO4S resolve: click", {
266      type: type,
267      id: id,
268      target: target,
269      has_params: !!params,
270    });
271
272    if (target === "_blank") {
273      pendingWindow = window.open("about:blank", "_blank");
274      if (pendingWindow) {
275        pendingWindow.opener = null;
276      }
277    }
278
279    fetchBannerData().then(function (data) {
280      var baseUrl = findBaseUrl(data, type, id);
281      var source = baseUrl ? "live_api" : "";
282      if (!baseUrl) {
283        baseUrl = findFallbackBaseUrl(type, id);
284        source = baseUrl ? "cached_fallback" : "";
285      }
286
287      var finalUrl = buildFinalUrl(baseUrl, params);
288      if (!finalUrl) {
289        logError("SEO4S cannot resolve URL:", { type: type, id: id });
290        return;
291      }
292
293      logInfo("SEO4S resolve: final URL ready", {
294        type: type,
295        id: id,
296        source: source,
297        base_url: baseUrl,
298      });
299      logResolveSource({
300        type: type,
301        id: id,
302        source: source,
303      });
304
305      if (target === "_blank") {
306        if (pendingWindow) {
307          pendingWindow.location.href = finalUrl;
308        } else {
309          window.open(finalUrl, "_blank", "noopener,noreferrer");
310        }
311      } else {
312        window.location.href = finalUrl;
313      }
314    });
315  }
316
317  function attachResolveHandler(link) {
318    if (!link || link.dataset.seo4sBound === "1") return;
319    link.dataset.seo4sBound = "1";
320    link.style.cursor = "pointer";
321
322    link.addEventListener("click", function (e) {
323      e.preventDefault();
324      openResolvedLink(link);
325    });
326  }
327
328  function resolveLinkTarget(el) {
329    if (!el) return null;
330    if (el.tagName && el.tagName.toLowerCase() === "a") return el;
331
332    var a = el.querySelector ? el.querySelector("a") : null;
333    if (a) return a;
334
335    var img = el.querySelector ? el.querySelector("img") : null;
336    if (img && img.parentNode) {
337      var wrap = document.createElement("a");
338      img.parentNode.insertBefore(wrap, img);
339      wrap.appendChild(img);
340      return wrap;
341    }
342
343    return el;
344  }
345
346  function applyResolveData(el, data, type) {
347    if (!el || !data || !data.id) return;
348    if (el.getAttribute("data-bc-skip") === "1") return;
349
350    var target = resolveLinkTarget(el);
351    if (!target) return;
352
353    target.setAttribute("href", "tracking-link");
354    target.classList.add("seo4s-resolve-link", "bc-hidden-link");
355    target.setAttribute("data-seo4s-resolve", "1");
356    target.setAttribute("data-type", type || "login_urls");
357    target.setAttribute("data-brand-id", data.id);
358    target.setAttribute("data-params", encodeParams(data.params || ""));
359    target.setAttribute("data-target", "_blank");
360    target.setAttribute("rel", "nofollow noopener");
361    attachResolveHandler(target);
362  }
363
364  function hasToplistUrlClass(el, id) {
365    if (!el || !el.classList || !id) return false;
366
367    var expected = "URL_" + String(id).toUpperCase();
368    for (var i = 0; i < el.classList.length; i++) {
369      if (String(el.classList[i]).toUpperCase() === expected) return true;
370    }
371
372    return false;
373  }
374
375  function bindToplistClasses() {
376    var paramsMap = cfg.toplist_params || {};
377    var ids = Object.keys(paramsMap);
378    if (!ids.length) return;
379
380    document.querySelectorAll("[class]").forEach(function (node) {
381      if (node.dataset && node.dataset.seo4sToplistBound === "1") return;
382
383      for (var i = 0; i < ids.length; i++) {
384        var id = ids[i];
385        if (!hasToplistUrlClass(node, id)) continue;
386
387        applyResolveData(node, {
388          id: id,
389          params: paramsMap[id] || "",
390        }, "banners_top");
391
392        if (node.dataset) node.dataset.seo4sToplistBound = "1";
393        break;
394      }
395    });
396  }
397
398  function bindButtons() {
399    if (!autoBind) return;
400
401    var main1 = cfg.main1_data || {};
402    var main2 = cfg.main2_data || {};
403    var main3 = cfg.main3_data || {};
404
405    if (main1.id) {
406      document.querySelectorAll(".header-button a.button, .btnMainSite").forEach(function (node) {
407        if (node.classList.contains("btnMainSite2") || node.classList.contains("btnMainSite3")) return;
408        applyResolveData(node, main1, "login_urls");
409      });
410    }
411
412    if (main2.id) {
413      document.querySelectorAll(".btnMainSite2").forEach(function (node) {
414        applyResolveData(node, main2, "login_urls");
415      });
416    }
417
418    if (main3.id) {
419      document.querySelectorAll(".btnMainSite3").forEach(function (node) {
420        applyResolveData(node, main3, "login_urls");
421      });
422    }
423  }
424
425  function bindAll() {
426    bindButtons();
427    bindToplistClasses();
428  }
429
430  function scheduleBind() {
431    if (bindTimer) window.clearTimeout(bindTimer);
432    bindTimer = window.setTimeout(bindAll, 50);
433  }
434
435  initSplide();
436  document.querySelectorAll("a[data-seo4s-resolve='1']").forEach(attachResolveHandler);
437  bindAll();
438  window.addEventListener("load", bindAll);
439  window.setTimeout(bindAll, 300);
440  window.setTimeout(bindAll, 1000);
441
442  if (window.MutationObserver) {
443    new MutationObserver(function (mutations) {
444      var shouldRebind = mutations.some(function (mutation) {
445        return mutation.addedNodes && mutation.addedNodes.length > 0;
446      });
447      if (shouldRebind) scheduleBind();
448    }).observe(document.body, {
449      childList: true,
450      subtree: true,
451    });
452  }
453});

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.