Commit ·
9c3f41f
1
Parent(s): b3b321f
fix: Quran XSS escape + 30s timeout + hide buttons during loading (same fixes as dialect)
Browse files- src/index.html +30 -6
src/index.html
CHANGED
|
@@ -1285,20 +1285,29 @@
|
|
| 1285 |
document.getElementById('quran-reference').textContent = '';
|
| 1286 |
document.getElementById('quran-translation-result').classList.add('is-hidden');
|
| 1287 |
document.getElementById('quran-lang-select').value = '';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1288 |
modal.classList.remove('is-hidden');
|
| 1289 |
document.body.style.overflow = 'hidden';
|
| 1290 |
|
|
|
|
|
|
|
| 1291 |
try {
|
| 1292 |
const res = await fetch('/api/quran', {
|
| 1293 |
method: 'POST',
|
| 1294 |
headers: { 'Content-Type': 'application/json' },
|
| 1295 |
-
body: JSON.stringify({ text: text, language: 'تدقيق الايات' })
|
|
|
|
| 1296 |
});
|
| 1297 |
const data = await res.json();
|
| 1298 |
|
| 1299 |
if (data.error) {
|
|
|
|
| 1300 |
document.getElementById('quran-uthmani-text').innerHTML =
|
| 1301 |
-
'<span class="text-secondary">' +
|
| 1302 |
return;
|
| 1303 |
}
|
| 1304 |
|
|
@@ -1317,8 +1326,11 @@
|
|
| 1317 |
document.getElementById('quran-copy-btn').classList.remove('is-hidden');
|
| 1318 |
|
| 1319 |
} catch (err) {
|
|
|
|
| 1320 |
document.getElementById('quran-uthmani-text').innerHTML =
|
| 1321 |
-
'<span class="text-secondary">
|
|
|
|
|
|
|
| 1322 |
}
|
| 1323 |
}
|
| 1324 |
|
|
@@ -1330,17 +1342,26 @@
|
|
| 1330 |
const textEl = document.getElementById('quran-translation-text');
|
| 1331 |
textEl.innerHTML = '<span class="text-secondary">⏳ جاري الترجمة...</span>';
|
| 1332 |
resultDiv.classList.remove('is-hidden');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1333 |
|
|
|
|
|
|
|
| 1334 |
try {
|
| 1335 |
const res = await fetch('/api/quran', {
|
| 1336 |
method: 'POST',
|
| 1337 |
headers: { 'Content-Type': 'application/json' },
|
| 1338 |
-
body: JSON.stringify({ text: _quranCurrentQuery, language: lang })
|
|
|
|
| 1339 |
});
|
| 1340 |
const data = await res.json();
|
| 1341 |
|
| 1342 |
if (data.error) {
|
| 1343 |
-
|
|
|
|
| 1344 |
return;
|
| 1345 |
}
|
| 1346 |
|
|
@@ -1364,7 +1385,10 @@
|
|
| 1364 |
document.getElementById('quran-copy-trans-btn').classList.remove('is-hidden');
|
| 1365 |
|
| 1366 |
} catch (err) {
|
| 1367 |
-
|
|
|
|
|
|
|
|
|
|
| 1368 |
}
|
| 1369 |
}
|
| 1370 |
|
|
|
|
| 1285 |
document.getElementById('quran-reference').textContent = '';
|
| 1286 |
document.getElementById('quran-translation-result').classList.add('is-hidden');
|
| 1287 |
document.getElementById('quran-lang-select').value = '';
|
| 1288 |
+
// Hide apply/copy until result
|
| 1289 |
+
var _applyBtn = document.getElementById('quran-apply-btn');
|
| 1290 |
+
var _copyBtn = document.getElementById('quran-copy-btn');
|
| 1291 |
+
if (_applyBtn) _applyBtn.classList.add('is-hidden');
|
| 1292 |
+
if (_copyBtn) _copyBtn.classList.add('is-hidden');
|
| 1293 |
modal.classList.remove('is-hidden');
|
| 1294 |
document.body.style.overflow = 'hidden';
|
| 1295 |
|
| 1296 |
+
var _qAbort = new AbortController();
|
| 1297 |
+
var _qTimeout = setTimeout(function(){ _qAbort.abort(); }, 30000);
|
| 1298 |
try {
|
| 1299 |
const res = await fetch('/api/quran', {
|
| 1300 |
method: 'POST',
|
| 1301 |
headers: { 'Content-Type': 'application/json' },
|
| 1302 |
+
body: JSON.stringify({ text: text, language: 'تدقيق الايات' }),
|
| 1303 |
+
signal: _qAbort.signal
|
| 1304 |
});
|
| 1305 |
const data = await res.json();
|
| 1306 |
|
| 1307 |
if (data.error) {
|
| 1308 |
+
var _escErr = data.error.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>');
|
| 1309 |
document.getElementById('quran-uthmani-text').innerHTML =
|
| 1310 |
+
'<span class="text-secondary">' + _escErr + '</span>';
|
| 1311 |
return;
|
| 1312 |
}
|
| 1313 |
|
|
|
|
| 1326 |
document.getElementById('quran-copy-btn').classList.remove('is-hidden');
|
| 1327 |
|
| 1328 |
} catch (err) {
|
| 1329 |
+
var _qMsg = err.name === 'AbortError' ? 'انتهى وقت الانتظار — حاول مرة أخرى' : 'حدث خطأ أثناء البحث — تأكد من الاتصال';
|
| 1330 |
document.getElementById('quran-uthmani-text').innerHTML =
|
| 1331 |
+
'<span class="text-secondary">' + _qMsg + '</span>';
|
| 1332 |
+
} finally {
|
| 1333 |
+
clearTimeout(_qTimeout);
|
| 1334 |
}
|
| 1335 |
}
|
| 1336 |
|
|
|
|
| 1342 |
const textEl = document.getElementById('quran-translation-text');
|
| 1343 |
textEl.innerHTML = '<span class="text-secondary">⏳ جاري الترجمة...</span>';
|
| 1344 |
resultDiv.classList.remove('is-hidden');
|
| 1345 |
+
// Hide apply/copy translation until result
|
| 1346 |
+
var _applyTransBtn = document.getElementById('quran-apply-trans-btn');
|
| 1347 |
+
var _copyTransBtn = document.getElementById('quran-copy-trans-btn');
|
| 1348 |
+
if (_applyTransBtn) _applyTransBtn.classList.add('is-hidden');
|
| 1349 |
+
if (_copyTransBtn) _copyTransBtn.classList.add('is-hidden');
|
| 1350 |
|
| 1351 |
+
var _tAbort = new AbortController();
|
| 1352 |
+
var _tTimeout = setTimeout(function(){ _tAbort.abort(); }, 30000);
|
| 1353 |
try {
|
| 1354 |
const res = await fetch('/api/quran', {
|
| 1355 |
method: 'POST',
|
| 1356 |
headers: { 'Content-Type': 'application/json' },
|
| 1357 |
+
body: JSON.stringify({ text: _quranCurrentQuery, language: lang }),
|
| 1358 |
+
signal: _tAbort.signal
|
| 1359 |
});
|
| 1360 |
const data = await res.json();
|
| 1361 |
|
| 1362 |
if (data.error) {
|
| 1363 |
+
var _escTErr = data.error.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>');
|
| 1364 |
+
textEl.innerHTML = '<span class="text-secondary">' + _escTErr + '</span>';
|
| 1365 |
return;
|
| 1366 |
}
|
| 1367 |
|
|
|
|
| 1385 |
document.getElementById('quran-copy-trans-btn').classList.remove('is-hidden');
|
| 1386 |
|
| 1387 |
} catch (err) {
|
| 1388 |
+
var _tMsg = err.name === 'AbortError' ? 'انتهى وقت الانتظار — حاول مرة أخرى' : 'حدث خطأ في الترجمة';
|
| 1389 |
+
textEl.innerHTML = '<span class="text-secondary">' + _tMsg + '</span>';
|
| 1390 |
+
} finally {
|
| 1391 |
+
clearTimeout(_tTimeout);
|
| 1392 |
}
|
| 1393 |
}
|
| 1394 |
|