1jQuery(document).ready(function ($) { 2 const $arrivalsTab = $('#tab-arrivals'); 3 const $departuresTab = $('#tab-departures'); 4 const $refreshButton = $('#yxs-refresh-button'); 5 const $panelContainer = $('#yxs-ifids-panels'); 6 const wrapper = document.getElementById('yxs-ifids-wrapper'); 7 const limit = wrapper ? wrapper.dataset.limit : null; 8 9 let lastRawTimestamp = null; 10 11 function togglePanel(type) { 12 const isArrivals = (type === 'arrivals'); 13 14 $arrivalsTab 15 .attr('aria-selected', isArrivals) 16 .toggleClass('yxs-ifids-widget__tab--active', isArrivals); 17 $departuresTab 18 .attr('aria-selected', !isArrivals) 19 .toggleClass('yxs-ifids-widget__tab--active', !isArrivals); 20 21 // Use prop() for boolean "hidden" 22 $('#panel-arrivals').prop('hidden', !isArrivals); 23 $('#panel-departures').prop('hidden', isArrivals); 24 25 // Update the table header 26 const headingText = isArrivals ? 'From' : 'To'; 27 $('#yxs-from-to-heading').text(headingText); 28 29 // Update EVERY rowâs mobile label (now a class, not an id) 30 const labelText = isArrivals ? 'From' : 'To'; 31 $('.yxs-from-to-label').text(labelText); 32 } 33 34 function shouldRefresh() { 35 if (!lastRawTimestamp) return true; 36 const then = new Date(lastRawTimestamp); // expects "YYYY-MM-DD HH:MM:SS" 37 const now = new Date(); 38 const elapsedMs = now - then; 39 return elapsedMs > (2 * 60 * 1000); 40 } 41 42 function loadPanels(refresh = false) { 43 if (refresh && !shouldRefresh()) { 44 const now = new Date(); 45 46 $('#ifids-update-status').text(`Flight have been updated below at ${new Date(new Date(lastRawTimestamp.replace(' ', 'T')).getTime() + 2*60*1000).toLocaleTimeString()}.`); 47 $('#yxs-last-updated strong').text(`Notice:`); 48 $('#yxs-last-updated span').text(`Refresh again at ${new Date(new Date(lastRawTimestamp.replace(' ', 'T')).getTime() + 2*60*1000).toLocaleTimeString()}.`); 49 return; 50 } 51 52 $panelContainer.html('<div class="yxs-ifids-widget__loading"><strong>Loading flights...</strong></div>'); 53 54 $.ajax({ 55 url: YXSIFIDS.ajaxurl, 56 method: 'GET', 57 data: { 58 action: 'yxs_ifids_get_panels', 59 refresh: refresh ? 1 : 0, 60 nonce: YXSIFIDS.nonce, 61 limit: limit, 62 }, 63 success: function (res) { 64 if (res.success) { 65 $panelContainer.html(res.data.html); 66 67 if (res.data.raw) { 68 lastRawTimestamp = res.data.raw; 69 } 70 71 if (res.data.timestamp) { 72 $('#yxs-last-updated span').text(res.data.timestamp); 73 } 74 75 const active = $arrivalsTab.attr('aria-selected') === 'true' ? 'arrivals' : 'departures'; 76 togglePanel(active); 77 78 // ð¥ Re-bind modal triggers after dynamic content load 79 bindFlightItemModal(); 80 } else { 81 $panelContainer.html('<p>Error loading flights.</p>'); 82 } 83 }, 84 error: function (xhr) { 85 $panelContainer.html('<p>AJAX error: ' + xhr.status + '</p>'); 86 } 87 }); 88 } 89 90 $arrivalsTab.on('click', () => togglePanel('arrivals')); 91 $departuresTab.on('click', () => togglePanel('departures')); 92 93 $refreshButton.on('click', function () { 94 loadPanels(true); 95 }); 96 97 function bindFlightItemModal() { 98 const $modal = $('#yxs-flight-modal'); 99 const $details = $('#yxs-flight-details'); 100 const $close = $('.yxs-ifids-modal__close'); 101 let $lastFocused = null; 102 103 function trapFocus(e) { 104 const focusable = $modal.find('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])').filter(':visible'); 105 const first = focusable[0]; 106 const last = focusable[focusable.length - 1]; 107 108 if (e.key === 'Tab') { 109 if (e.shiftKey && document.activeElement === first) { 110 e.preventDefault(); 111 last.focus(); 112 } else if (!e.shiftKey && document.activeElement === last) { 113 e.preventDefault(); 114 first.focus(); 115 } 116 } 117 } 118 119 $('.yxs-ifids-widget__item').on('click', function () { 120 const $item = $(this); 121 const isArrivals = $('#panel-arrivals').is(':visible'); 122const fromToLabel = isArrivals ? 'Arriving From' : 'Departing To'; 123const fromToClass = isArrivals ? 'arriving-from' : 'departing-to'; 124 125const fields = { 126 [fromToLabel]: { value: $item.data('from'), class: fromToClass }, 127 'Flight #': { value: $item.data('flight'), class: 'flight-number' }, 128 'Airline': { value: $item.data('airline'), class: 'airline' }, 129 'Scheduled Time': { value: $item.data('scheduled'), class: 'scheduled-time' }, 130 'Status': { value: $item.data('status'), class: 'status' }, 131 'Baggage': { value: $item.data('baggage'), class: 'baggage' } 132}; 133 134 $details.empty(); 135 $.each(fields, function (label, obj) { 136 $details.append(` 137 <li class="yxs-ifids-modal__details-item yxs-ifids-modal__details-item--${obj.class}">
138 <span class="yxs-ifids-modal__details-label">${label}:</span> ${obj.value || 'â'} 139 </li>`); 140 }); 141 142 $lastFocused = $(document.activeElement); 143 $modal.removeAttr('hidden').show(); 144 $('body').addClass('yxs-modal-open'); 145 $modal[0].focus(); 146 147 $(document).on('keydown.modalTrap', trapFocus); 148 }); 149 150 function closeModal() { 151 $modal.hide().attr('hidden', true); 152 $('body').removeClass('yxs-modal-open'); 153 $(document).off('keydown.modalTrap'); 154 if ($lastFocused) $lastFocused.focus(); 155 } 156 157 $close.on('click', closeModal); 158 159 $(document).on('keydown', function (e) { 160 if (e.key === 'Escape') { 161 closeModal(); 162 } 163 }); 164 } 165 166 loadPanels(); // initial load 167});
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.