1/** 2 * Responsive Videos Handler. 3 * 4 * Handles switching video sources based on viewport size for responsive video backgrounds. 5 * Works with both container and slider blocks that have responsive video backgrounds. 6 * 7 * @since x.x.x 8 */ 9 10( function () { 11 'use strict'; 12 13 // Spectra breakpoints (matching the responsive controls system). 14 const BREAKPOINTS = { 15 lg: 1024, // Desktop: 1024px and above. 16 md: 768, // Tablet: 768px to 1023.98px. 17 sm: 0, // Mobile: 0px to 767.98px. 18 }; 19 20 /** 21 * Get current device type based on viewport width. 22 * 23 * @return {string} Device type: 'lg', 'md', or 'sm'. 24 */ 25 function getCurrentDevice() { 26 const width = window.innerWidth; 27 28 if ( width >= BREAKPOINTS.lg ) { 29 return 'lg'; 30 } else if ( width >= BREAKPOINTS.md ) { 31 return 'md'; 32 } 33 34 return 'sm'; 35 } 36 37 /** 38 * Update video source based on current device and available responsive videos. 39 * 40 * @param {HTMLElement} container The container element with data-responsive-videos attribute. 41 */ 42 function updateVideoSource( container ) { 43 const video = container.querySelector( '.spectra-background-video__wrapper video' ); 44 45 if ( ! video ) { 46 return; 47 } 48 49 const responsiveVideosData = container.getAttribute( 'data-responsive-videos' ); 50 51 if ( ! responsiveVideosData ) { 52 return; 53 } 54 55 let responsiveVideos; 56 try { 57 responsiveVideos = JSON.parse( responsiveVideosData ); 58 } catch ( error ) { 59 return; 60 } 61 62 const currentDevice = getCurrentDevice(); 63 64 // Check if device actually changed. 65 const lastDevice = container.getAttribute( 'data-last-device' ); 66 if ( lastDevice === currentDevice ) { 67 return; 68 } 69 70 const fallbackOrder = { 71 sm: [ 'sm', 'md', 'lg' ], // Mobile: mobile -> tablet -> desktop. 72 md: [ 'md', 'lg' ], // Tablet: tablet -> desktop. 73 lg: [ 'lg' ], // Desktop: desktop only. 74 }; 75 76 // Find the appropriate video URL using fallback hierarchy. 77 let videoUrl = null; 78 const deviceOrder = fallbackOrder[ currentDevice ] || [ 'lg' ]; 79 80 for ( const device of deviceOrder ) { 81 if ( responsiveVideos[ device ] ) { 82 videoUrl = responsiveVideos[ device ]; 83 break; 84 } 85 } 86 87 // Only update if URL is different from current source. 88 const source = video.querySelector( 'source' ); 89 const currentSrc = source ? source.src : video.src; 90 91 if ( videoUrl && currentSrc !== videoUrl ) { 92 // Update source. 93 if ( source ) { 94 source.src = videoUrl; 95 } else { 96 video.src = videoUrl; 97 } 98 99 // Reload video. 100 video.load(); 101 } 102 103 // Update the last device. 104 container.setAttribute( 'data-last-device', currentDevice ); 105 } 106 107 /** 108 * Initialize responsive videos for all elements on the page. 109 */ 110 function initResponsiveVideos() { 111 const containers = document.querySelectorAll( '[data-responsive-videos]' ); 112 113 containers.forEach( function ( container ) { 114 updateVideoSource( container ); 115 } ); 116 } 117 118 /** 119 * Handle window resize events with debouncing. 120 */ 121 let resizeTimeout; 122 function handleResize() { 123 clearTimeout( resizeTimeout ); 124 resizeTimeout = setTimeout( function () { 125 initResponsiveVideos(); 126 }, 250 ); // 250ms debounce. 127 } 128 129 /** 130 * Initialize when DOM is ready. 131 */ 132 function init() { 133 // Skip initial setup to prevent flicker on page load. 134 // Videos will use their default source from PHP. 135 136 // Mark all containers as initialized with current device. 137 const containers = document.querySelectorAll( '[data-responsive-videos]' ); 138 const currentDevice = getCurrentDevice(); 139 containers.forEach( function ( container ) { 140 container.setAttribute( 'data-last-device', currentDevice ); 141 } ); 142 143 // Listen for window resize events. 144 window.addEventListener( 'resize', handleResize ); 145 146 // Also listen for orientation change on mobile devices. 147 window.addEventListener( 'orientationchange', function () { 148 setTimeout( initResponsiveVideos, 500 ); 149 } ); 150 } 151 152 // Initialize when DOM is ready. 153 if ( document.readyState === 'loading' ) { 154 document.addEventListener( 'DOMContentLoaded', init ); 155 } else { 156 init(); 157 } 158} )();
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.