PageSourceSearch

https://hostinkos.com/en/assets/hk-kerkese/modal.js?v=20260916iframe

js hostinkos.com collected 2026-10-08 18:43:19 UTC 10,519 bytes, 336 lines download raw bytes

1/**
2 * hk-kerkese modal — isolated opener for https://web.hostinkos.com/
3 * Desktop: modal + iframe on web.hostinkos.com (PHP + Turnstile live there);
4 *   if iframe fails ready ping → new tab
5 * Mobile: full-page navigate
6 *
7 * Note: do NOT embed apex /web/ — origin PHP under /web/*.php is broken
8 * ("No input file specified") and Turnstile is bound to web.hostinkos.com.
9 */
10(function () {
11  var BASE = "https://web.hostinkos.com/";
12  var FORM_ORIGINS = {
13    "https://web.hostinkos.com": 1
14  };
15  var ALLOWED_PARENTS = {
16    "https://hostinkos.com": 1,
17    "https://www.hostinkos.com": 1
18  };
19  var READY_MS = 8000;
20  /** Bump when form HTML/JS changes — forces iframe past CF/browser cache */
21  var EMBED_CACHE_BUST = "20260916nisje";
22  var PAKO_ALIAS = {
23    "web-mini": "web-nisje",
24    "web-pro": "web-biznes",
25    "web-pro-plus": "web-biznes-plus",
26    "web-shop": "web-dyqan",
27    "web-shop-max": "web-dyqan-pro",
28    "web-shop-custom": "web-dyqan-plus"
29  };
30
31  function normalizeFormParams(u) {
32    var pako = u.searchParams.get("pako");
33    if (pako && PAKO_ALIAS[pako]) u.searchParams.set("pako", PAKO_ALIAS[pako]);
34    var need = u.searchParams.get("need");
35    if (need && PAKO_ALIAS[need]) {
36      u.searchParams.set("need", "webfaqe_re");
37      if (!u.searchParams.get("pako")) u.searchParams.set("pako", PAKO_ALIAS[need]);
38    } else if (need === "mini" || need === "landing" || need === "web-mini") {
39      u.searchParams.set("need", "webfaqe_re");
40      if (!u.searchParams.get("pako")) u.searchParams.set("pako", "web-nisje");
41    }
42  }
43
44  var isEn =
45    (document.documentElement.lang || "").toLowerCase().indexOf("en") === 0 ||
46    (window.location.pathname || "").indexOf("/en/") === 0;
47
48  var T = isEn
49    ? {
50        close: "Close",
51        title: "Website request",
52        thanks: "Thank you — your request was sent",
53        msgEmail: "We will reply by email.",
54        msgPhone: "We will contact you by phone or WhatsApp during office hours.",
55        openTab: "Open the form in a new tab",
56        frameTitle: "Website request form"
57      }
58    : {
59        close: "Mbyll",
60        title: "Kërkesë për webfaqe",
61        thanks: "Faleminderit — kërkesa u dërgua",
62        msgEmail: "Ju kthejmë përgjigje me email.",
63        msgPhone: "Do t'ju kontaktojmë me telefon ose WhatsApp në orarin e zyrës.",
64        openTab: "Hap formularin në tab të ri",
65        frameTitle: "Formular kërkese webfaqe"
66      };
67
68  var modal = null;
69  var frame = null;
70  var openTab = null;
71  var successEl = null;
72  var successMsgEl = null;
73  var fallbackEl = null;
74  var lastFocus = null;
75  var readyTimer = null;
76  var awaitingReady = false;
77  var pendingTabUrl = "";
78
79  function isMobile() {
80    return window.matchMedia("(max-width: 767px)").matches;
81  }
82
83  function buildUrl(el, forModal) {
84    var u = new URL(BASE);
85    var pako = el.getAttribute("data-pako");
86    var need = el.getAttribute("data-need");
87    if (pako) u.searchParams.set("pako", pako);
88    if (need) u.searchParams.set("need", need);
89    var href = el.getAttribute("href");
90    if ((!pako && !need) && href && href.indexOf("web.hostinkos.com") !== -1) {
91      try {
92        var fromHref = new URL(href, window.location.href);
93        fromHref.searchParams.forEach(function (val, key) {
94          if (key === "embed") return;
95          if (!u.searchParams.has(key)) u.searchParams.set(key, val);
96        });
97      } catch (eHref) {}
98    }
99    if (forModal) {
100      u.searchParams.set("embed", "1");
101      u.searchParams.set("_v", EMBED_CACHE_BUST);
102      u.searchParams.set("_t", String(Date.now()));
103    }
104    normalizeFormParams(u);
105    return u.toString();
106  }
107
108  function clearReadyWatch() {
109    awaitingReady = false;
110    if (readyTimer) {
111      clearTimeout(readyTimer);
112      readyTimer = null;
113    }
114  }
115
116  function openInNewTab(url) {
117    clearReadyWatch();
118    var u = url || pendingTabUrl || BASE;
119    try {
120      var w = window.open(u, "_blank", "noopener,noreferrer");
121      if (!w) {
122        // Popup blocked — same-tab navigate
123        window.location.href = u;
124        return;
125      }
126    } catch (eOpen) {
127      window.location.href = u;
128      return;
129    }
130    closeKerkeseQuiet();
131  }
132
133  function cacheNodes() {
134    frame = modal.querySelector("#hkKerkeseFrame") || modal.querySelector("iframe");
135    openTab = modal.querySelector("#hkKerkeseOpenTab");
136    successEl = modal.querySelector("#hkKerkeseSuccess");
137    successMsgEl = modal.querySelector("#hkKerkeseSuccessMsg");
138    fallbackEl = modal.querySelector(".hk-kerkese-modal__fallback");
139  }
140
141  function ensureModal() {
142    var existing = document.getElementById("hkKerkeseModal");
143    if (existing && !existing.querySelector("iframe.hk-kerkese-modal__frame")) {
144      existing.remove();
145      existing = null;
146      modal = null;
147    }
148    if (modal && document.body.contains(modal) && modal.querySelector("iframe")) {
149      cacheNodes();
150      return modal;
151    }
152    if (existing) existing.remove();
153    modal = document.createElement("div");
154    modal.id = "hkKerkeseModal";
155    modal.className = "hk-kerkese-modal";
156    modal.setAttribute("hidden", "");
157    modal.innerHTML =
158      '<button type="button" class="hk-kerkese-modal__backdrop" data-hk-close aria-label="' +
159      T.close +
160      '"></button>' +
161      '<div class="hk-kerkese-modal__dialog" role="dialog" aria-modal="true" aria-label="' +
162      T.title +
163      '">' +
164      '<button type="button" class="hk-kerkese-modal__close" data-hk-close aria-label="' +
165      T.close +
166      '">
166×</button>' +
167      '<iframe class="hk-kerkese-modal__frame" id="hkKerkeseFrame" title="' +
168      T.frameTitle +
169      '" src="about:blank"></iframe>' +
170      '<div class="hk-kerkese-modal__success" id="hkKerkeseSuccess" hidden tabindex="-1" role="status" aria-live="polite">' +
171      "<h2>" +
172      T.thanks +
173      "</h2>" +
174      '<p class="hk-kerkese-modal__success-msg" id="hkKerkeseSuccessMsg"></p>' +
175      '<button type="button" class="hk-kerkese-modal__success-btn" data-hk-close>' +
176      T.close +
177      "</button>" +
178      "</div>" +
179      '<p class="hk-kerkese-modal__fallback">' +
180      '<a id="hkKerkeseOpenTab" href="' +
181      BASE +
182      '" target="_blank" rel="noopener noreferrer">' +
183      T.openTab +
184      "</a>" +
185      "</p></div>";
186    document.body.appendChild(modal);
187    cacheNodes();
188    modal.querySelectorAll("[data-hk-close]").forEach(function (el) {
189      el.addEventListener("click", closeKerkese);
190    });
191    if (frame) {
192      frame.addEventListener("error", function () {
193        if (awaitingReady) openInNewTab(pendingTabUrl);
194      });
195    }
196    return modal;
197  }
198
199  function showFormView() {
200    if (frame) {
201      frame.hidden = false;
202      frame.removeAttribute("hidden");
203      frame.removeAttribute("aria-hidden");
204    }
205    if (successEl) {
206      successEl.hidden = true;
207      successEl.setAttribute("hidden", "");
208    }
209    if (fallbackEl) {
210      fallbackEl.hidden = false;
211      fallbackEl.removeAttribute("hidden");
212    }
213    if (modal) modal.classList.remove("hk-kerkese-modal--success");
214  }
215
216  function showSuccessView(channel) {
217    clearReadyWatch();
218    ensureModal();
219    var msg = channel === "phone_or_wa" ? T.msgPhone : T.msgEmail;
220    if (successMsgEl) successMsgEl.textContent = msg;
221    if (frame) {
222      frame.hidden = true;
223      frame.setAttribute("hidden", "");
224      frame.setAttribute("aria-hidden", "true");
225      frame.src = "about:blank";
226    }
227    if (fallbackEl) {
228      fallbackEl.hidden = true;
229      fallbackEl.setAttribute("hidden", "");
230    }
231    if (successEl) {
232      successEl.hidden = false;
233      successEl.removeAttribute("hidden");
234      try {
235        successEl.focus();
236      } catch (eFocus) {}
237    }
238    if (modal) modal.classList.add("hk-kerkese-modal--success");
239  }
240
241  function startReadyWatch(tabUrl) {
242    clearReadyWatch();
243    awaitingReady = true;
244    pendingTabUrl = tabUrl;
245    readyTimer = setTimeout(function () {
246      if (awaitingReady) openInNewTab(tabUrl);
247    }, READY_MS);
248  }
249
250  function openKerkese(el) {
251    var tabUrl = buildUrl(el, false);
252    if (isMobile()) {
253      window.location.href = tabUrl;
254      return;
255    }
256    try {
257      var embedUrl = buildUrl(el, true);
258      ensureModal();
259      showFormView();
260      lastFocus = document.activeElement;
261      if (openTab) openTab.href = tabUrl;
262      if (!frame) {
263        openInNewTab(tabUrl);
264        return;
265      }
266      startReadyWatch(tabUrl);
267      // Force a real reload (same-origin iframe can keep a stale cached document)
268      try {
269        frame.src = "about:blank";
270      } catch (eBlank) {}
271      frame.src = embedUrl;
272      modal.hidden = false;
273      modal.removeAttribute("hidden");
274      document.body.classList.add("hk-kerkese-modal-open");
275      // Modal itself didn't become visible → new tab
276      if (modal.hidden || modal.getAttribute("hidden") !== null) {
277        openInNewTab(tabUrl);
278        return;
279      }
280      var closeBtn = modal.querySelector(".hk-kerkese-modal__close");
281      if (closeBtn) {
282        try {
283          closeBtn.focus();
284        } catch (eFocus) {}
285      }
286    } catch (eOpen) {
287      openInNewTab(tabUrl);
288    }
289  }
290
291  function closeKerkeseQuiet() {
292    clearReadyWatch();
293    if (!modal) return;
294    modal.hidden = true;
295    modal.setAttribute("hidden", "");
296    document.body.classList.remove("hk-kerkese-modal-open");
297    if (frame) frame.src = "about:blank";
298  }
299
300  function closeKerkese() {
301    clearReadyWatch();
302    if (!modal || modal.hidden) return;
303    modal.hidden = true;
304    modal.setAttribute("hidden", "");
305    document.body.classList.remove("hk-kerkese-modal-open");
306    showFormView();
307    if (frame) frame.src = "about:blank";
308    if (lastFocus && typeof lastFocus.focus === "function") {
309      try {
310        lastFocus.focus();
311      } catch (eBack) {}
312    }
313  }
314
315  document.addEventListener("click", function (e) {
316    var el = e.target.closest(".js-hk-kerkese");
317    if (!el) return;
318    e.preventDefault();
319    openKerkese(el);
320  });
321  document.addEventListener("keydown", function (e) {
322    if (e.key === "Escape") closeKerkese();
323  });
324  window.addEventListener("message", function (e) {
325    if (!FORM_ORIGINS[e.origin]) return;
326    if (!e.data || !e.data.type) return;
327    if (!ALLOWED_PARENTS[window.location.origin]) return;
328    if (e.data.type === "hk-kerkese-ready") {
329      clearReadyWatch();
330      return;
331    }
332    if (e.data.type === "hk-kerkese-success") {
333      showSuccessView(e.data.reply_channel || "email");
334    }
335  });
336})();

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.