1/** 2 * Gullstrom Events â AJAX month navigation. 3 * 4 * Swaps the month grid without a full page reload, updating the URL so back / 5 * forward and refresh keep the month. Progressive enhancement: with JavaScript 6 * disabled the `?ge_month=YYYY-MM` links still navigate normally, and any fetch 7 * failure falls back to a full page load. The handler is delegated from the 8 * document so it survives grid swaps. 9 */ 10(function () { 11 'use strict'; 12 13 var cfg = window.geCalendar || {}; 14 var REST = cfg.restUrl || ''; 15 16 /* ----------------------------------- Event slider (Bricks Splide) */ 17 18 function initSliders() { 19 if ( typeof window.Splide === 'undefined' ) { 20 return; // Splide (Bricks) not loaded â slides fall back to a scroll row. 21 } 22 var sliders = document.querySelectorAll( '.ge-slider' ); 23 Array.prototype.forEach.call( sliders, function ( el ) { 24 if ( el.dataset.geMounted ) { 25 return; 26 } 27 el.dataset.geMounted = '1'; 28 new window.Splide( el, { 29 type: 'slide', 30 start: 0, 31 perPage: 4, 32 perMove: 1, 33 gap: '16px', 34 speed: 400, 35 arrows: true, 36 pagination: false, 37 keyboard: 'global', 38 pauseOnHover: true, 39 pauseOnFocus: true, 40 mediaQuery: 'max', 41 breakpoints: { 42 1279: { perPage: 4 }, 43 991: { perPage: 2 }, 44 767: { perPage: 2 }, 45 478: { perPage: 1 } 46 } 47 } ).mount(); 48 } ); 49 } 50 51 if ( document.readyState === 'loading' ) { 52 document.addEventListener( 'DOMContentLoaded', initSliders ); 53 } else { 54 initSliders(); 55 } 56 // Retry once everything (incl. Splide) has loaded; init is idempotent. 57 window.addEventListener( 'load', initSliders ); 58 59 /* ----------------------------------------------- AJAX month navigation */ 60 61 if ( ! REST ) { 62 return; 63 } 64 65 function fallback( month ) { 66 var url = new URL( window.location.href ); 67 url.searchParams.set( 'ge_month', month ); 68 window.location.href = url.toString(); 69 } 70 71 function loadMonth( calendar, month, push ) { 72 if ( ! calendar || ! month ) { 73 return; 74 } 75 76 calendar.classList.add( 'ge-calendar--loading' ); 77 calendar.setAttribute( 'aria-busy', 'true' ); 78 79 var endpoint = REST + ( REST.indexOf( '?' ) === -1 ? '?' : '&' ) + 80 'month=' + encodeURIComponent( month ) + 81 '&base=' + encodeURIComponent( window.location.href ); 82 83 fetch( endpoint, { headers: { Accept: 'application/json' }, credentials: 'same-origin' } ) 84 .then( function ( r ) { 85 return r.ok ? r.json() : Promise.reject( r.status ); 86 } ) 87 .then( function ( data ) { 88 if ( ! data || ! data.html ) { 89 throw new Error( 'empty response' ); 90 } 91 var tmp = document.createElement( 'div' ); 92 tmp.innerHTML = data.html; 93 var fresh = tmp.querySelector( '.ge-calendar' ); 94 if ( ! fresh ) { 95 throw new Error( 'no calendar in response' ); 96 } 97 98 calendar.replaceWith( fresh ); 99 100 if ( push ) { 101 var url = new URL( window.location.href ); 102 url.searchParams.set( 'ge_month', data.month ); 103 window.history.pushState( { geMonth: data.month }, '', url.toString() ); 104 } 105 106 var label = fresh.querySelector( '.ge-calendar__label' ); 107 if ( label ) { 108 label.setAttribute( 'tabindex', '-1' ); 109 label.focus(); 110 } 111 } ) 112 .catch( function () { 113 fallback( month ); 114 } ); 115 } 116 117 document.addEventListener( 'click', function ( e ) { 118 if ( ! e.target.closest ) { 119 return; 120 } 121 var link = e.target.closest( '.ge-calendar__nav, .ge-calendar__today' ); 122 if ( ! link ) { 123 return; 124 } 125 var calendar = link.closest( '.ge-calendar' ); 126 var month = link.getAttribute( 'data-ge-month' ); 127 if ( ! calendar || ! month ) { 128 return; 129 } 130 if ( e.metaKey || e.ctrlKey || e.shiftKey || e.altKey ) { 131 return; 132 } 133 e.preventDefault(); 134 loadMonth( calendar, month, true ); 135 } ); 136 137 var firstCalendar = document.querySelector( '.ge-calendar' ); 138 var initialMonth = firstCalendar ? firstCalendar.getAttribute( 'data-ge-month' ) : ''; 139 140 window.addEventListener( 'popstate', function () { 141 var calendar = document.querySelector( '.ge-calendar' ); 142 if ( ! calendar ) { 143 return; 144 } 145 var month = new URL( window.location.href ).searchParams.get( 'ge_month' ) || initialMonth; 146 if ( month && month !== calendar.getAttribute( 'data-ge-month' ) ) { 147 loadMonth( calendar, month, false ); 148 } 149 } ); 150})();
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.