PageSourceSearch

https://www.compunnel.com/core/views/b456f3d487/assets/js/page-banner-video.js

js compunnel.com collected 2026-10-02 03:02:33 UTC 7,400 bytes, 286 lines download raw bytes

1(function ($) {
2  function getOwlInstance($carousel) {
3    try {
4      return $carousel && $carousel.data ? $carousel.data('owl.carousel') : null;
5    } catch (e) {
6      return null;
7    }
8  }
9
10  function ensureVideoSourceLoaded(videoEl) {
11    var $video = $(videoEl);
12    var $source = $video.find('source[data-src]');
13    if ($source.length && !$source.attr('src')) {
14      // Lazy slide: promote data-src → src and trigger load
15      $source.attr('src', $source.attr('data-src'));
16      try {
17        videoEl.load();
18      } catch (e) {
19        // ignore
20      }
21    }
22    // First slide already has src set server-side — nothing extra needed.
23  }
24
25  function preloadVideoInItem($item) {
26    if (!$item || !$item.length) return;
27    var videoEl = $item.find('video.banner-bg-video-el').first().get(0);
28    if (!videoEl) return;
29
30    ensureVideoSourceLoaded(videoEl);
31    try {
32      // Fully buffer adjacent slides (not just metadata) so the next video is
33      // ready to play the instant it becomes active — removes the frozen-poster
34      // "pause" at slide change.
35      videoEl.preload = 'auto';
36      videoEl.muted = true;
37      videoEl.playsInline = true;
38      videoEl.loop = false;
39      if (videoEl.readyState < 2) {
40        try { videoEl.load(); } catch (e) { /* ignore */ }
41      }
42    } catch (e) {
43      // ignore
44    }
45  }
46
47  // Defer work until the page has loaded and the main thread is idle. Buffering
48  // slides the visitor cannot see must never compete with the LCP image for
49  // bandwidth, so neighbour preloading waits for this on the first pass.
50  function afterPageSettled(fn) {
51    function run() {
52      if (window.requestIdleCallback) {
53        window.requestIdleCallback(fn, { timeout: 3000 });
54      } else {
55        setTimeout(fn, 1000);
56      }
57    }
58    if (document.readyState === 'complete') {
59      run();
60    } else {
61      $(window).one('load', run);
62    }
63  }
64
65  function pauseAllVideos($scope) {
66    $scope.find('video.banner-bg-video-el').each(function () {
67      try {
68        this.pause();
69      } catch (e) {
70        // ignore
71      }
72
73	  try {
74		$(this).closest('.banner-bg-video').removeClass('is-playing');
75	  } catch (e) {
76		// ignore
77	  }
78    });
79  }
80
81  function stopAutoplay($carousel) {
82    var owl = getOwlInstance($carousel);
83    if (!owl) return;
84    try {
85      $carousel.trigger('stop.owl.autoplay');
86    } catch (e) {
87      // ignore
88    }
89  }
90
91  function resumeAutoplay($carousel) {
92    var owl = getOwlInstance($carousel);
93    if (!owl) return;
94    if (!owl.settings || !owl.settings.autoplay) return;
95
96    var timeout = $carousel.data('defaultAutoplayTimeout');
97    if (!timeout) {
98      timeout = owl.settings.autoplayTimeout || 7000;
99      $carousel.data('defaultAutoplayTimeout', timeout);
100    }
101
102    try {
103      $carousel.trigger('play.owl.autoplay', [timeout]);
104    } catch (e) {
105      // ignore
106    }
107  }
108
109  function bindEndedOnce(videoEl, $carousel) {
110    var $video = $(videoEl);
111    if ($video.data('endedBound')) return;
112    $video.data('endedBound', true);
113
114    videoEl.addEventListener(
115      'ended',
116      function () {
117        try {
118          if ($video.closest('.owl-item').hasClass('active')) {
119            $carousel.trigger('next.owl.carousel');
120          }
121        } catch (e) {
122          // ignore
123        }
124      },
125      false
126    );
127  }
128
129  function restartAndPlay(videoEl) {
130    var started = false;
131  var $wrapper = null;
132  try {
133    $wrapper = $(videoEl).closest('.banner-bg-video');
134    $wrapper.removeClass('is-playing');
135  } catch (e) {
136    $wrapper = null;
137  }
138
139    try {
140      videoEl.muted = true;
141      videoEl.playsInline = true;
142      videoEl.loop = false;
143      // Encourage buffering while active.
144      videoEl.preload = 'auto';
145    } catch (e) {
146      // ignore
147    }
148
149    var tryStart = function () {
150      if (started) return;
151      started = true;
152
153      try {
154        videoEl.currentTime = 0;
155      } catch (e) {
156        // ignore
157      }
158
159      try {
160        var promise = videoEl.play();
161        if (promise && typeof promise.catch === 'function') {
162          promise.catch(function () {
163            // Autoplay might be blocked; ignore.
164          });
165        }
166      } catch (e) {
167        // ignore
168      }
169    };
170
171  try {
172    // Fade in only when we actually start rendering video frames.
173    videoEl.addEventListener(
174      'playing',
175      function () {
176        try {
177          if ($wrapper && $wrapper.length) $wrapper.addClass('is-playing');
178        } catch (e) {
179          // ignore
180        }
181      },
182      { once: true }
183    );
184  } catch (e) {
185    // ignore
186  }
187
188    if (videoEl.readyState >= 1) {
189      tryStart();
190      return;
191    }
192
193    try {
194      videoEl.addEventListener('loadedmetadata', tryStart, { once: true });
195      videoEl.addEventListener('canplay', tryStart, { once: true });
196    } catch (e) {
197      // ignore
198    }
199  }
200
201  function handleCarousel($carousel) {
202    var owl = getOwlInstance($carousel);
203    if (!owl) return;
204
205    // De-dupe duplicate owl events for the same logical slide.
206    var relIndex = null;
207    try {
208      relIndex = owl.relative(owl.current());
209    } catch (e) {
210      relIndex = null;
211    }
212    if (relIndex !== null && $carousel.data('lastRelIndex') === relIndex) {
213      return;
214    }
215    $carousel.data('lastRelIndex', relIndex);
216
217    pauseAllVideos($carousel);
218
219    var $activeItem = $carousel.find('.owl-item.active').first();
220    var $activeVideos = $activeItem.find('video.banner-bg-video-el');
221
222    if (!$activeVideos.length) {
223      resumeAutoplay($carousel);
224      return;
225    }
226
227    // Video slide: stop Owl autoplay and advance on video ended.
228    stopAutoplay($carousel);
229
230    // Preload adjacent items for smoother next/prev (covers loop wrap-around).
231    try {
232      var currentAbs = owl.current();
233      var $items = $carousel.find('.owl-item');
234
235      // The active slide is about to play, so it is always warmed immediately.
236      preloadVideoInItem($items.eq(currentAbs));
237
238      var preloadNeighbours = function () {
239        preloadVideoInItem($items.eq(currentAbs + 1));
240        preloadVideoInItem($items.eq(currentAbs - 1));
241        preloadVideoInItem($items.first());
242        preloadVideoInItem($items.last());
243      };
244
245      // On the very first pass this runs during initial page load, where
246      // buffering up to four ~1MB videos starves the LCP image. Hold the
247      // neighbours until the page is idle; once warmed, later slide changes
248      // preload straight away so next/prev stays instant.
249      if ($carousel.data('bannerVideoWarmed')) {
250        preloadNeighbours();
251      } else {
252        $carousel.data('bannerVideoWarmed', true);
253        afterPageSettled(preloadNeighbours);
254      }
255    } catch (e) {
256      // ignore
257    }
258
259    $activeVideos.each(function () {
260      try {
261        ensureVideoSourceLoaded(this);
262        bindEndedOnce(this, $carousel);
263        restartAndPlay(this);
264      } catch (e) {
265        // ignore
266      }
267    });
268  }
269
270  $(function () {
271    $('.page-banner-slider, #home_banner_slider').each(function () {
272      var $carousel = $(this);
273
274      $carousel.on('initialized.owl.carousel translated.owl.carousel', function () {
275        setTimeout(function () {
276          handleCarousel($carousel);
277        }, 0);
278      });
279
280      // In case Owl is already initialized.
281      setTimeout(function () {
282        handleCarousel($carousel);
283      }, 0);
284    });
285  });
286})(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.