diff --git a/assets/js/main.js b/assets/js/main.js index 2bb0c77..3e4b39e 100644 --- a/assets/js/main.js +++ b/assets/js/main.js @@ -10,7 +10,7 @@ document.addEventListener('DOMContentLoaded', () => { try { await navigator.clipboard.writeText(text); const original = button.textContent; - button.textContent = 'Copied'; + button.textContent = document.documentElement.lang === 'ar' ? 'تم النسخ' : 'Copied'; setTimeout(() => { button.textContent = original; }, 1200); @@ -42,25 +42,25 @@ document.addEventListener('DOMContentLoaded', () => { searchInput.addEventListener('input', applyFilter); } - // Convert alerts to SweetAlert2 popups - (async function() { - if (typeof Swal === 'undefined') return; - const alerts = document.querySelectorAll('.alert'); - for (const alertEl of alerts) { - // Don't convert if it contains interactive elements - if (alertEl.querySelector('form, ul, .btn, .alert-heading, a')) continue; - - // Skip empty states / full page notices - const siblings = Array.from(alertEl.parentElement.children).filter(el => el !== alertEl && el.tagName !== 'SCRIPT' && el.tagName !== 'STYLE' && el.tagName !== 'BR'); - if (siblings.length === 0 && (alertEl.parentElement.classList.contains('container') || alertEl.parentElement.tagName === 'MAIN' || alertEl.parentElement.classList.contains('col-12'))) { - continue; + // Convert SweetAlert2 popups + if (typeof Swal !== 'undefined') { + + // 1. Convert Flash Alerts (success, danger, warning) + const validAlerts = []; + document.querySelectorAll('.alert').forEach(alertEl => { + // Must be one of the flash message types + if (!alertEl.classList.contains('alert-success') && + !alertEl.classList.contains('alert-danger') && + !alertEl.classList.contains('alert-warning')) { + return; } - // Skip heavily padded elements (likely structural empty states) - if (alertEl.classList.contains('py-4') || alertEl.classList.contains('py-5') || alertEl.classList.contains('py-3') || alertEl.classList.contains('alert-info')) { - continue; // Also explicitly skipping alert-info because they are usually informational structure blocks - } - + // Skip if it contains interactive elements + if (alertEl.querySelector('form, ul, .btn, .alert-heading, a')) return; + + const text = alertEl.innerText.trim(); + if (!text) return; + let type = 'info'; let titleStr = document.documentElement.lang === 'ar' ? 'ملاحظة' : 'Note'; @@ -75,18 +75,66 @@ document.addEventListener('DOMContentLoaded', () => { titleStr = document.documentElement.lang === 'ar' ? 'تنبيه' : 'Warning'; } - const text = alertEl.innerText.trim(); - if (!text) continue; - + // Hide immediately to prevent flash alertEl.style.display = 'none'; + + validAlerts.push({ type, titleStr, text }); + }); - await Swal.fire({ - icon: type, - title: titleStr, - text: text, - confirmButtonText: document.documentElement.lang === 'ar' ? 'حسنًا' : 'OK', - confirmButtonColor: '#0d6efd' + // Process alerts sequentially so they don't overlap + (async function() { + for (const alertData of validAlerts) { + await Swal.fire({ + icon: alertData.type, + title: alertData.titleStr, + text: alertData.text, + confirmButtonText: document.documentElement.lang === 'ar' ? 'حسنًا' : 'OK', + confirmButtonColor: '#0d6efd' + }); + } + })(); + + // 2. Convert standard browser confirm() dialogs (Forms & Links) + const interceptConfirms = (selector, eventType, triggerAction) => { + document.querySelectorAll(selector).forEach(el => { + const jsAttr = el.getAttribute('on' + eventType); + if (jsAttr && jsAttr.includes('confirm(')) { + // Extract text from inside confirm('...') + const match = jsAttr.match(/confirm\(\s*['"](.*?)['"]\s*\)/); + const confirmText = match ? match[1] : (document.documentElement.lang === 'ar' ? 'هل أنت متأكد؟' : 'Are you sure?'); + + // Remove native confirm + el.removeAttribute('on' + eventType); + + el.addEventListener(eventType, function(e) { + e.preventDefault(); + Swal.fire({ + title: document.documentElement.lang === 'ar' ? 'تأكيد' : 'Confirmation', + text: confirmText, + icon: 'warning', + showCancelButton: true, + confirmButtonColor: '#dc3545', + cancelButtonColor: '#6c757d', + confirmButtonText: document.documentElement.lang === 'ar' ? 'نعم، متأكد' : 'Yes, I am sure', + cancelButtonText: document.documentElement.lang === 'ar' ? 'إلغاء' : 'Cancel' + }).then((result) => { + if (result.isConfirmed) { + triggerAction(el); + } + }); + }); + } }); - } - })(); + }; + + // Forms + interceptConfirms('form[onsubmit*="confirm"]', 'submit', (form) => { + HTMLFormElement.prototype.submit.call(form); + }); + + // Links (a tags) + interceptConfirms('a[onclick*="confirm"]', 'click', (link) => { + window.location.href = link.getAttribute('href'); + }); + } }); \ No newline at end of file diff --git a/cookie.txt b/cookie.txt index 5140534..4bcd372 100644 --- a/cookie.txt +++ b/cookie.txt @@ -2,4 +2,4 @@ # https://curl.se/docs/http-cookies.html # This file was generated by libcurl! Edit at your own risk. -localhost FALSE / FALSE 0 PHPSESSID tf03tbhu7e9rjeotatir4nlali +127.0.0.1 FALSE / FALSE 0 PHPSESSID dc35afddvci5n93ei5dp4uaegu