PageSourceSearch

https://danetechnologies.com/wp-content/themes/Divi-child/custom.js?ver=1.1.0

js danetechnologies.com collected 2026-10-07 01:42:10 UTC 14,142 bytes, 457 lines download raw bytes

1/* dane custom.js: lean init + lazy third-party */
2(function ($) {
3  "use strict";
4
5  /* ---------- utils ---------- */
6
7  function throttle(fn, wait) {
8    var t = 0;
9    return function () {
10      var now = Date.now();
11      if (now - t > wait) {
12        t = now;
13        fn.apply(this, arguments);
14      }
15    };
16  }
17
18  function loadStyle(href) {
19    return new Promise(function (res, rej) {
20      if (document.querySelector('link[href="' + href + '"]')) return res();
21      var l = document.createElement("link");
22      l.rel = "stylesheet";
23      l.href = href;
24      l.onload = res;
25      l.onerror = rej;
26      document.head.appendChild(l);
27    });
28  }
29
30  function loadScript(src) {
31    return new Promise(function (res, rej) {
32      if (document.querySelector('script[src="' + src + '"]')) {
33        return setTimeout(res, 0);
34      }
35      var s = document.createElement("script");
36      s.src = src;
37      s.async = true;
38      s.defer = true;
39      s.onload = res;
40      s.onerror = rej;
41      document.head.appendChild(s);
42    });
43  }
44
45  function onIdle(fn, timeout) {
46    if ("requestIdleCallback" in window) {
47      requestIdleCallback(fn, { timeout: timeout || 1200 });
48    } else {
49      setTimeout(fn, timeout || 600);
50    }
51  }
52
53  /* ---------- 1) button: add class when text === Learn More ---------- */
54  function flagLearnMoreButtons() {
55    $(".et_pb_button").each(function () {
56      if ($(this).text().trim().toLowerCase() === "learn more") {
57        $(this).addClass("learn-more-btn-hide");
58      }
59    });
60  }
61
62  /* ---------- 2) SLICK: init only when visible + library ready ---------- */
63  var SLICK_JS = "https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick.min.js";
64  var SLICK_CSS = "https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick.min.css";
65  var SLICK_THEME = "https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick-theme.min.css";
66
67  function ensureSlick() {
68    if ($.fn && $.fn.slick) return Promise.resolve();
69    return Promise.all([loadStyle(SLICK_CSS), loadStyle(SLICK_THEME), loadScript(SLICK_JS)]);
70  }
71
72  function initOneSlick($carousel) {
73    if ($carousel.data("slick-initialized")) return;
74    $carousel.data("slick-initialized", true);
75
76    var $pagination = $('<div class="dane-carousel-pagination">' +
77      '<button class="dane-carousel-prev"><img src="/wp-content/uploads/dane-icons_chevron-left-red.svg" alt="Previous"></button>' +
78      '<button class="dane-carousel-next"><img src="/wp-content/uploads/dane-icons_chevron-right-red.svg" alt="Next"></button>' +
79      "</div>");
80
81    var hasMultiple = $carousel.find(".dane-carousel-slide").length > 1;
82
83    if (hasMultiple) {
84      $carousel.after($pagination);
85    }
86
87    $carousel.on("init", function () {
88      $carousel.closest(".dane-carousel-container").addClass("loaded");
89    });
90
91    $carousel.slick({
92      infinite: true,
93      slidesToShow: 1,
94      slidesToScroll: 1,
95      autoplay: !!hasMultiple,
96      autoplaySpeed: 3000,
97      arrows: !!hasMultiple,
98      prevArrow: hasMultiple ? $pagination.find(".dane-carousel-prev") : undefined,
99      nextArrow: hasMultiple ? $pagination.find(".dane-carousel-next") : undefined,
100      pauseOnHover: true,
101      fade: true,
102      lazyLoad: "ondemand",
103      responsive: [
104        {
105          breakpoint: 768,
106          settings: { slidesToShow: 1, slidesToScroll: 1, arrows: false }
107        }
108      ]
109    });
110  }
111
112  function initSlickWhenVisible() {
113    var $carousels = $(".dane-carousel");
114    if (!$carousels.length) return;
115
116    var io = "IntersectionObserver" in window ? new IntersectionObserver(function (entries) {
117      entries.forEach(function (entry) {
118        if (!entry.isIntersecting) return;
119        var el = entry.target;
120        io.unobserve(el);
121        ensureSlick().then(function () { initOneSlick($(el)); });
122      });
123    }, { rootMargin: "200px 0px" }) : null;
124
125    $carousels.each(function () {
126      if (io) {
127        io.observe(this);
128      } else {
129        onIdle(function () {
130          ensureSlick().then(function () { initOneSlick($(this)); }.bind(this));
131        }, 600);
132      }
133    });
134
135    $(window).on("resize", throttle(function () {
136      $(".dane-carousel.slick-initialized").slick("setPosition");
137    }, 300));
138  }
139
140  /* ---------- 3) LIGHTBOX: lazy-load Magnific on first click ---------- */
141  var MFP_JS = "https://cdnjs.cloudflare.com/ajax/libs/magnific-popup.js/1.1.0/jquery.magnific-popup.min.js";
142  var MFP_CSS = "https://cdnjs.cloudflare.com/ajax/libs/magnific-popup.js/1.1.0/magnific-popup.min.css";
143
144  function ensureMagnific() {
145    if ($.magnificPopup && $.magnificPopup.open) return Promise.resolve();
146    return Promise.all([loadStyle(MFP_CSS), loadScript(MFP_JS)]);
147  }
148
149  $(document).on("click", "a.lightbox-trigger", function (e) {
150    e.preventDefault();
151    var href = $(this).attr("href");
152    ensureMagnific().then(function () {
153      $.magnificPopup.open({
154        items: { src: href },
155        type: "image",
156        gallery: { enabled: true },
157        callbacks: {
158          open: function () {
159            $(".mfp-img").css({
160              minWidth: "40vw",
161              width: "auto",
162              height: "auto",
163              maxWidth: "90vw",
164              maxHeight: "90vh"
165            });
166          }
167        }
168      });
169    });
170  });
171
172  /* ---------- 4) scrolling strip ---------- */
173  function setupScrolling() {
174    var $wrap = $(".scrolling-wrap").first();
175    if (!$wrap.length || $wrap.data("cloned")) return;
176    var $clone = $wrap.clone();
177    $wrap.after($clone);
178    $wrap.data("cloned", true);
179
180    var totalWidth = $wrap[0].scrollWidth;
181    var pxPerSec = 180;
182    var duration = Math.max(10, Math.min(120, totalWidth / pxPerSec));
183
184    $wrap.css("animation-duration", duration + "s");
185    $clone.css("animation-duration", duration + "s");
186  }
187
188  /* ---------- 5) accordion ---------- */
189  /*
190  function bindAccordion() {
191    $(".et_pb_accordion .et_pb_toggle_open")
192      .addClass("et_pb_toggle_close")
193      .removeClass("et_pb_toggle_open");
194
195    $(".et_pb_toggle_title").on("click", function () {
196      var $toggle = $(this).closest(".et_pb_toggle");
197      var $acc = $toggle.closest(".et_pb_accordion");
198      if ($acc.hasClass("et_pb_accordion_toggling")) return;
199      $acc.addClass("et_pb_accordion_toggling");
200
201      $toggle.find(".et_pb_toggle_content").slideToggle(300, function () {
202        $toggle.toggleClass("et_pb_toggle_open et_pb_toggle_close");
203        setTimeout(function () { $acc.removeClass("et_pb_accordion_toggling"); }, 50);
204      });
205    });
206  }
207  */
208
209  /* ---------- 6) minor DOM tidies ---------- */
210  function tidyDOM() {
211    $("p").filter(function () { return this.textContent.trim() === "" && this.children.length === 0; }).remove();
212
213    function removeOnMobile() {
214      if (window.innerWidth <= 768) $(".remove-on-mobile").remove();
215    }
216    removeOnMobile();
217    $(window).on("resize", throttle(removeOnMobile, 250));
218
219    $(".side_by_btn_column").each(function () {
220      var $btnParents = $(this).find(".et_pb_button").parent();
221      if ($btnParents.length > 1 && !$(this).find(".side-by-side-wrap").length) {
222        $btnParents.wrapAll('<div class="side-by-side-wrap"></div>');
223      }
224    });
225
226    $(".add-checkmark-class li").addClass("checkmark");
227    $(".add-arrow-right-class li").addClass("arrow-right");
228  }
229
230  /* ---------- 7) menu arrows ---------- */
231  function decorateMenu() {
232    var $links = $("#menu-primary-menu-desktop li a");
233    $links.each(function () {
234      var txt = $(this).text().toLowerCase();
235      if (/(products|sectors|resources|about|contact)/.test(txt)) {
236        if ($(this).find("img.down-arrow").length) return;
237        $(this).append(' <img class="down-arrow default-arrow" src="/wp-content/uploads/dane-icons_carrot-down-black.svg" alt="down arrow">');
238        $(this).append(' <img class="down-arrow hover-arrow" src="/wp-content/uploads/dane-icons_carrot-down-red.svg" alt="down arrow">');
239      }
240    });
241  }
242
243  /* ---------- HERO VIDEO: drop-in optimized ---------- */
244  (function () {
245    "use strict";
246
247    let built = false;
248
249    function inViewport(el) {
250      const r = el.getBoundingClientRect();
251      return r.top < window.innerHeight && r.bottom > 0 && r.left < window.innerWidth && r.right > 0;
252    }
253
254    function build() {
255      if (built) return;
256
257      const root = document.getElementById("bh-hero");
258      if (!root) return;
259
260      const holder = root.querySelector(".bh-hero__media");
261      if (!holder) return;
262
263      const mp4 = (root.dataset.mp4 || "").trim();
264      const posterURL = (root.dataset.poster || "").trim();
265      if (!mp4) return;
266
267      let posterEl = holder.querySelector("img.bh-hero__poster") || null;
268
269      if (!posterEl && posterURL) {
270        const pre = new Image();
271        pre.decoding = "async";
272        pre.onload = function () {
273          posterEl = document.createElement("img");
274          posterEl.className = "bh-hero__poster";
275          posterEl.src = posterURL;
276          posterEl.fetchPriority = "high";
277          holder.appendChild(posterEl);
278        };
279        pre.src = posterURL;
280      } else if (posterEl) {
281        try { posterEl.fetchPriority = "high"; } catch (_) {}
282      }
283
284      const v = document.createElement("video");
285      v.autoplay = true;
286      v.loop = true;
287      v.muted = true;
288      v.playsInline = true;
289      v.preload = "metadata";
290      v.setAttribute("aria-hidden", "true");
291
292      /* ensure correct sizing from first paint */
293      v.style.position = "absolute";
294      v.style.inset = "0";
295      v.style.width = "100%";
296      v.style.height = "100%";
297      v.style.objectFit = "cover";
298      v.style.objectPosition = "center";
299      v.style.opacity = "0";
300      v.style.background = "#000";
301      v.style.transition = "opacity .35s ease";
302      v.style.display = "block";
303
304      const reveal = () => {
305        v.style.opacity = "1";
306        if (posterEl) posterEl.style.opacity = "0";
307        v.play().catch(() => {});
308      };
309
310      v.addEventListener("loadedmetadata", () => {
311        try { if (v.readyState < 2) v.currentTime = 0.05; } catch (_) {}
312      }, { once: true });
313
314      v.addEventListener("seeked", reveal, { once: true });
315      v.addEventListener("loadeddata", reveal, { once: true });
316      v.addEventListener("playing", reveal, { once: true });
317      v.addEventListener("error", (e) => console.error("[bh-hero] video error", e));
318
319      requestAnimationFrame(() => {
320        holder.appendChild(v);
321        v.src = mp4;
322      });
323
324      setTimeout(() => {
325        if (getComputedStyle(v).opacity === "0") reveal();
326      }, 1800);
327
328      built = true;
329    }
330
331    function init() {
332      const root = document.getElementById("bh-hero");
333      if (!root) return;
334
335      if ("IntersectionObserver" in window) {
336        const io = new IntersectionObserver((entries) => {
337          if (entries[0].isIntersecting) {
338            build();
339            io.disconnect();
340          }
341        }, { rootMargin: "400px" });
342        io.observe(root);
343      }
344
345      if (inViewport(root)) build();
346
347      const onScroll = () => { if (inViewport(root)) build(); };
348      window.addEventListener("scroll", onScroll, { passive: true });
349      window.addEventListener("resize", onScroll, { passive: true });
350
351      setTimeout(build, 1200);
352    }
353
354    if (document.readyState === "loading") {
355      document.addEventListener("DOMContentLoaded", init);
356    } else {
357      init();
358    }
359  })();
360
361  /* ---------- 9) reCAPTCHA lazy loader ---------- */
362  (function () {
363    var loaded = false;
364    var srcV2or3 = null;
365
366    function inferRecaptchaSrc() {
367      return "https://www.gstatic.com/recaptcha/releases/naPR4A6FAh-yZLuCX253WaZq/recaptcha__en.js";
368    }
369
370    function loadRecaptcha() {
371      if (loaded) return;
372      loaded = true;
373      if (!srcV2or3) srcV2or3 = inferRecaptchaSrc();
374      loadScript(srcV2or3).catch(function(){ loaded = false; });
375    }
376
377    function watchForms() {
378      var candidates = document.querySelectorAll(
379        ".wpforms-form, form[action*='wpforms'], .g-recaptcha, [data-recaptcha], .wpcf7-form"
380      );
381      if (!candidates.length) return;
382
383      if ("IntersectionObserver" in window) {
384        var io = new IntersectionObserver(function (entries) {
385          entries.forEach(function (e) {
386            if (e.isIntersecting) { loadRecaptcha(); io.disconnect(); }
387          });
388        }, { rootMargin: "300px" });
389
390        candidates.forEach(function (el) { io.observe(el); });
391      }
392
393      ["click", "focusin", "touchstart"].forEach(function (evt) {
394        document.addEventListener(evt, loadRecaptcha, { once: true, passive: true });
395      });
396
397      onIdle(loadRecaptcha, 3000);
398    }
399
400    $(function(){ watchForms(); });
401  })();
402
403  /* ---------- ready ---------- */
404  $(function () {
405    flagLearnMoreButtons();
406    tidyDOM();
407    // bindAccordion();
408    if ($(".scrolling-wrap").length) onIdle(setupScrolling, 500);
409    onIdle(initSlickWhenVisible, 400);
410    decorateMenu();
411  });
412
413  /* ---------- AIR DEMO MODAL ---------- */
414  function initAirDemoModal() {
415    var $trigger = $(".air-demo-trigger");
416    var $modal = $(".air-demo-modal");
417
418    if (!$trigger.length || !$modal.length) return;
419
420    $trigger.on("click", function (e) {
421      e.preventDefault();
422      $modal.css("display", "flex");
423      $("body").addClass("air-demo-open");
424    });
425
426    $(document).on("click", ".air-demo-close", function () {
427      $modal.hide();
428      $("body").removeClass("air-demo-open");
429    });
430
431    $modal.on("click", function (e) {
432      if ($(e.target).closest(".wpforms-container, .air-demo-close").length) return;
433      $modal.hide();
434      $("body").removeClass("air-demo-open");
435    });
436
437    $(document).on("keydown", function (e) {
438      if (e.key === "Escape") {
439        $modal.hide();
440        $("body").removeClass("air-demo-open");
441      }
442    });
443  }
444
445  /* ---------- ready ---------- */
446  $(function () {
447    flagLearnMoreButtons();
448    tidyDOM();
449    // bindAccordion();
450    if ($(".scrolling-wrap").length) onIdle(setupScrolling, 500);
451    onIdle(initSlickWhenVisible, 400);
452    decorateMenu();
453
454    initAirDemoModal();
455  });
456
457})(jQuery);

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.