1// Wait for DOM to be ready 2jQuery(document).ready(function ($) { 3 // YouTube Video Modal Control - Consolidated Function for Multiple Modals 4 function initializeYouTubeModalControl() { 5 // Initialize control for each video modal 6 $('.video-modal').each(function () { 7 const $modal = $(this); 8 const modalId = $modal.attr('id'); 9 let modalIsOpen = false; 10 let originalVideoSrc = ''; 11 12 // Get modal elements 13 const $modalTriggers = $('a[data-toggle="modal"][data-target="#' + modalId + '"]'); 14 const $closeButtons = $('#' + modalId + ' .close'); 15 16 // Function to stop YouTube video for this modal 17 function stopYouTubeVideo() { 18 if (!modalIsOpen) return; 19 20 modalIsOpen = false; 21 22 const $iframe = $modal.find('iframe'); 23 if ($iframe.length) { 24 // Stop video by clearing src 25 $iframe.attr('src', ''); 26 27 // Restore original src after a short delay 28 setTimeout(function () { 29 if (originalVideoSrc) { 30 $iframe.attr('src', originalVideoSrc); 31 } 32 }, 100); 33 34 // Trigger custom event 35 $(document).trigger('modalVideoStopped', [originalVideoSrc, modalId]); 36 } 37 } 38 39 // CUSTOM TRIGGER: When modal open button is clicked 40 $modalTriggers.on('click', function (e) { 41 // Store original video src when modal opens 42 setTimeout(function () { 43 if ($modal.hasClass('in') || $modal.css('display') === 'block') { 44 const $iframe = $modal.find('iframe'); 45 if ($iframe.length) { 46 originalVideoSrc = $iframe.attr('src'); 47 modalIsOpen = true; 48 49 // Trigger custom event 50 $(document).trigger('modalVideoStarted', [originalVideoSrc, modalId]); 51 } 52 } 53 }, 300); // Wait for modal to actually open 54 }); 55 56 // CUSTOM TRIGGER: Close button click 57 $closeButtons.on('click', function () { 58 stopYouTubeVideo(); 59 }); 60 61 // CUSTOM TRIGGER: Click outside modal (backdrop click) 62 $modal.on('click', function (e) { 63 // Check if click is on backdrop (not on modal content) 64 if (e.target === this) { 65 stopYouTubeVideo(); 66 } 67 }); 68 69 // CUSTOM TRIGGER: ESC key press 70 $(document).on('keydown', function (e) { 71 if (e.keyCode === 27 && modalIsOpen) { // ESC key 72 stopYouTubeVideo(); 73 } 74 }); 75 76 // CUSTOM TRIGGER: Manual modal hide detection 77 setInterval(function () { 78 const isCurrentlyOpen = $modal.hasClass('in') || $modal.css('display') === 'block'; 79 80 if (modalIsOpen && !isCurrentlyOpen) { 81 stopYouTubeVideo(); 82 } else if (!modalIsOpen && isCurrentlyOpen) { 83 modalIsOpen = true; 84 } 85 }, 500); 86 }); 87 } 88 89 // Smooth scroll functionality (global: any in-page anchor link) 90 // Delegated on document so links added later (megamenu, dynamic content) work too 91 function initializeSmoothScroll() { 92 $(document).on('click', 'a[href^="#"]', function (event) { 93 var target = $(this).attr('href'); 94 if (target === '#' || target.length < 2) { 95 return; 96 } 97 // Skip Bootstrap-driven links (tabs, collapse, carousel) and 98 // links that already opt in via .smooth-scroll-link (handled below) 99 if ($(this).attr('data-toggle') || $(this).hasClass('smooth-scroll-link')) { 100 return; 101 } 102 // Only handle links that point to a real element on this page 103 if ($(target).length) { 104 event.preventDefault(); 105 $('html, body').animate({ 106 scrollTop: $(target).offset().top 107 }, 800, 'swing'); 108 } 109 }); 110 } 111 112 // Remove empty P tags functionality 113 function removeEmptyPTags() { 114 // Check if jQuery is loaded 115 if (typeof jQuery === 'undefined') { 116 return 0; 117 } 118 119 let removedCount = 0; 120 121 // Find all empty p tags and remove them 122 jQuery('p').each(function () { 123 const $p = jQuery(this); 124 125 // Check if paragraph is empty (no text content after trimming) 126 const textContent = $p.text().trim(); 127 const hasMeaningfulContent = textContent !== '' || 128 $p.find('img[src]').length > 0 || 129 $p.find('form').length > 0 || 130 $p.find('button, input, select, textarea, a[href]').length > 0; 131 132 // If no meaningful content, remove the paragraph 133 if (!hasMeaningfulContent) { 134 $p.remove(); 135 removedCount++; 136 } 137 }); 138 139 return removedCount; 140 } 141 142 // Calculate and set max-height for Choose a course tabs (NEW VERSION ONLY) 143 function initializeChooseCourseTabHeight() { 144 var $section = $('.choose_a_course_new .tabCollapse.v-tabs'); 145 if (!$section.length) return; 146
147 var $navTabs = $section.find('ul.nav.nav-tabs'); 148 var $tabContent = $section.find('.tab-content'); 149 150 function updateTabHeight() { 151 var contentHeight = $tabContent.outerHeight(); 152 var h4Height = $('.choose_a_course_new .main_row .col-md-3 h4').outerHeight() || 0; 153 var offset = h4Height + 20; // h4 height + 20px margin-top of ul 154 155 if (contentHeight > 0) { 156 $navTabs.css('max-height', (contentHeight - offset) + 'px'); 157 } 158 } 159 160 // Run on load and resize 161 $(window).on('load resize', function() { 162 updateTabHeight(); 163 }); 164 165 // Run when tab is changed 166 $navTabs.find('a[data-toggle="tab"]').on('shown.bs.tab', function () { 167 updateTabHeight(); 168 }); 169 170 // Initial call 171 updateTabHeight(); 172 } 173 174 // Initialize all functionality 175 initializeYouTubeModalControl(); 176 initializeSmoothScroll(); 177 removeEmptyPTags(); 178 initializeChooseCourseTabHeight(); 179 180}); 181 182/* --------------------------- 183 Fashion courses section Tabs Slider for Mobile 184----------------------------*/ 185jQuery(document).ready(function ($) { 186 187 if ($(window).width() > 767) return; 188 189 var $sections = $( 190 '.page-template-newprogramwithcourses section#fashion_courses_section, \ 191 .page-template-programwithoutcourses section#fashion_courses_section' 192 ); 193 194 $sections.each(function () { 195 196 var $section = $(this); 197 var $nav = $section.find('ul.nav.nav-tabs'); 198 var $tabs = $nav.find('li'); 199 var total = $tabs.length; 200 var current = 0; 201 202 if (!$nav.length) return; 203 204 /* -------------------------------- 205 Wrap UL inside .fc-slider 206 -------------------------------- */ 207 if (!$nav.parent().hasClass('fc-slider')) { 208 $nav.wrap('<div class="fc-slider"></div>'); 209 } 210 211 var $sliderWrap = $section.find('.fc-slider'); 212 213 /* Inject arrows inside wrapper */ 214 if (!$sliderWrap.find('.mobile-tab-arrow').length) { 215 $sliderWrap.append('<span class="mobile-tab-arrow left disabled"></span>'); 216 $sliderWrap.append('<span class="mobile-tab-arrow right"></span>'); 217 } 218 219 /* Inject dots inside wrapper */ 220 if (!$sliderWrap.find('.mobile-tab-dots').length) { 221 222 var dotsWrap = $('<div class="mobile-tab-dots"></div>'); 223 224 $tabs.each(function (i) { 225 dotsWrap.append('<span data-index="' + i + '"></span>'); 226 }); 227 228 $sliderWrap.append(dotsWrap); 229 } 230 231 /* Helper: get current translateX */ 232 function getTranslateX($el) { 233 var style = window.getComputedStyle($el[0]); 234 var matrix = style.transform; 235 236 if (matrix === 'none') return 0; 237 238 var values = matrix.match(/matrix.*\((.+)\)/)[1].split(', '); 239 return parseFloat(values[4]); 240 } 241 242 function centerSlide(index) { 243 244 current = index; 245 246 var $activeItem = $tabs.eq(index); 247 248 var containerWidth = $sliderWrap.outerWidth(); 249 var itemWidth = $activeItem.outerWidth(true); 250 var itemLeft = $activeItem.position().left; 251 252 var currentTranslate = getTranslateX($nav); 253 254 var newTranslate = 255 currentTranslate - itemLeft + (containerWidth / 2) - (itemWidth / 2); 256 257 $nav.css('transform', 'translateX(' + newTranslate + 'px)'); 258 259 /* Update dots */ 260 $sliderWrap.find('.mobile-tab-dots span') 261 .removeClass('active') 262 .eq(index).addClass('active'); 263 264 /* Arrow state */ 265 $sliderWrap.find('.mobile-tab-arrow.left') 266 .toggleClass('disabled', index === 0); 267 268 $sliderWrap.find('.mobile-tab-arrow.right') 269 .toggleClass('disabled', index === total - 1); 270 } 271 272 /* Arrow click â ONLY SLIDE */ 273 $sliderWrap.on('click', '.mobile-tab-arrow.right', function () { 274 if (current < total - 1) { 275 centerSlide(current + 1); 276 } 277 }); 278 279 $sliderWrap.on('click', '.mobile-tab-arrow.left', function () { 280 if (current > 0) { 281 centerSlide(current - 1); 282 } 283 }); 284 285 /* Dot click */ 286 $sliderWrap.on('click', '.mobile-tab-dots span', function () { 287 centerSlide($(this).data('index')); 288 }); 289 290 /* When actual tab is clicked â change content + center */ 291 $tabs.find('a').on('shown.bs.tab', function (e) { 292 293 var index = $(e.target).parent().index(); 294 295 current = index; 296 centerSlide(index); 297 298 /* Fix slick */ 299 setTimeout(function () { 300 $section.find('.main_slider, .thumb_slider, .require_slidernew') 301 .each(function () { 302 if ($(this).hasClass('slick-initialized')) { 303 $(this).slick('setPosition'); 304 } 305 }); 306 }, 100); 307 }); 308 309 /* Initial */ 310 centerSlide(0); 311 312 }); 313 314});
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.