1(function(){ 2 'use strict'; 3 4 function qs(root, sel){ return root ? root.querySelector(sel) : null; } 5 6 function removeOldUrlParam(){ 7 try { 8 var url = new URL(window.location.href); 9 if (url.searchParams.has('h24mp_city')) { 10 url.searchParams.delete('h24mp_city'); 11 var clean = url.pathname + (url.searchParams.toString() ? '?' + url.searchParams.toString() : '') + url.hash; 12 window.history.replaceState({}, document.title, clean); 13 } 14 } catch(e) {} 15 } 16 17 function val(value){ 18 return (value === null || typeof value === 'undefined' || value === '') ? '-' : String(value); 19 } 20 21 function setText(root, field, value){ 22 var el = qs(root, '[data-h24mp-field="' + field + '"]'); 23 if (!el) return; 24 25 value = val(value); 26 27 // Generic label system: PHP can define data-h24mp-prefix and data-h24mp-suffix. 28 // This prevents AJAX from removing labels like Max, Min, Humidité, Vent. 29 if (el.hasAttribute('data-h24mp-prefix') || el.hasAttribute('data-h24mp-suffix')) { 30 el.textContent = (el.getAttribute('data-h24mp-prefix') || '') + value + (el.getAttribute('data-h24mp-suffix') || ''); 31 return; 32 } 33 34 switch (field) { 35 case 'current_temperature': 36 el.textContent = value + '°'; 37 break; 38 case 'temperature_max': 39 el.textContent = 'Max ' + value + '°'; 40 break; 41 case 'temperature_min': 42 el.textContent = 'Min ' + value + '°'; 43 break; 44 case 'humidity': 45 el.textContent = 'Humidité ' + value + ' %'; 46 break; 47 case 'wind_speed': 48 el.textContent = 'Vent ' + value + ' km/h'; 49 break; 50 default: 51 el.textContent = value; 52 break; 53 } 54 } 55 56 function esc(s){ 57 return String(s === null || typeof s === 'undefined' ? '' : s) 58 .replace(/&/g,'&') 59 .replace(/</g,'<') 60 .replace(/>/g,'>') 61 .replace(/"/g,'"') 62 .replace(/'/g,'''); 63 } 64 65 function updateWidget(widget, payload){ 66 if (!widget || !payload || !payload.weather || !payload.prayer) return; 67 68 var w = payload.weather; 69 var p = payload.prayer; 70 71 setText(widget, 'city', payload.city || ''); 72 setText(widget, 'current_temperature', w.current_temperature); 73 setText(widget, 'status', w.status); 74 setText(widget, 'temperature_max', w.temperature_max); 75 setText(widget, 'temperature_min', w.temperature_min); 76 setText(widget, 'humidity', w.humidity); 77 setText(widget, 'wind_speed', w.wind_speed); 78 79 setText(widget, 'fajr', p.fajr); 80 setText(widget, 'sunrise', p.sunrise); 81 setText(widget, 'dhuhr', p.dhuhr); 82 setText(widget, 'asr', p.asr); 83 setText(widget, 'maghrib', p.maghrib); 84 setText(widget, 'isha', p.isha); 85 86 var list = qs(widget, '[data-h24mp-forecast]'); 87 if (list && Array.isArray(payload.forecast)) { 88 list.innerHTML = payload.forecast.map(function(f){ 89 return '<div class="h24mp-forecast-row"><span>' + esc(f.day_name) + '</span><span>' + esc(f.temperature_min) + '° / ' + esc(f.temperature_max) + '°</span></div>'; 90 }).join(''); 91 } 92 } 93 94 function fetchCity(widget, city){ 95 if (!window.H24MP || !H24MP.ajaxUrl || !widget) return; 96 97 removeOldUrlParam(); 98 widget.classList.add('is-loading'); 99 widget.classList.remove('is-error'); 100 101 var body = new URLSearchParams(); 102 body.append('action', 'h24mp_get_city_data'); 103 body.append('nonce', H24MP.nonce || ''); 104 body.append('city', city || 'casablanca'); 105 106 fetch(H24MP.ajaxUrl, { 107 method: 'POST', 108 credentials: 'same-origin', 109 headers: {'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8'}, 110 body: body.toString() 111 }) 112 .then(function(r){ return r.json(); }) 113 .then(function(json){ 114 if (!json || !json.success || !json.data) throw new Error('bad response'); 115 updateWidget(widget, json.data); 116 widget.dataset.city = city; 117 removeOldUrlParam(); 118 }) 119 .catch(function(){ widget.classList.add('is-error'); }) 120 .finally(function(){ widget.classList.remove('is-loading'); }); 121 } 122 123 document.addEventListener('DOMContentLoaded', removeOldUrlParam); 124 removeOldUrlParam(); 125 126 document.addEventListener('submit', function(e){ 127 var form = e.target.closest ? e.target.closest('[data-h24mp-widget] form, form') : null; 128 if (form && form.querySelector && form.querySelector('[data-h24mp-city-select]')) { 129 e.preventDefault(); 130 return false;
131 } 132 }, true); 133 134 document.addEventListener('change', function(e){ 135 var select = e.target.closest && e.target.closest('[data-h24mp-city-select]'); 136 if (!select) return; 137 138 e.preventDefault(); 139 e.stopPropagation(); 140 141 var widget = select.closest('[data-h24mp-widget]'); 142 if (!widget) return; 143 144 fetchCity(widget, select.value); 145 return false; 146 }, true); 147})();
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.