Commit ·
2ab3a0a
1
Parent(s): 791e26d
Fix: Apply buttons now REPLACE text (not append), add translation reference/copy/apply buttons
Browse files- src/index.html +109 -7
src/index.html
CHANGED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
|
| 2 |
<html lang="ar" dir="rtl" class="h-full">
|
| 3 |
<head>
|
| 4 |
<meta charset="UTF-8">
|
|
@@ -968,6 +968,11 @@
|
|
| 968 |
</div>
|
| 969 |
<div id="quran-inline-translation" class="is-hidden p-4 rounded-xl" style="background:rgba(6,182,212,0.06); border:1px solid rgba(6,182,212,0.15);">
|
| 970 |
<p id="quran-inline-trans-text" style="font-size:18px; line-height:2; color:var(--color-text-primary); text-align:center;"></p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 971 |
</div>
|
| 972 |
</div>
|
| 973 |
</div>
|
|
@@ -1435,12 +1440,19 @@
|
|
| 1435 |
}
|
| 1436 |
}
|
| 1437 |
|
|
|
|
|
|
|
|
|
|
| 1438 |
async function translateQuranInline() {
|
| 1439 |
var lang = document.getElementById('quran-inline-lang').value;
|
| 1440 |
if (!lang || !_quranInlineQuery) return;
|
| 1441 |
var resultDiv = document.getElementById('quran-inline-translation');
|
| 1442 |
var textEl = document.getElementById('quran-inline-trans-text');
|
|
|
|
|
|
|
| 1443 |
textEl.innerHTML = '<span class="text-secondary">⏳ جاري الترجمة...</span>';
|
|
|
|
|
|
|
| 1444 |
resultDiv.classList.remove('is-hidden');
|
| 1445 |
var _abortCtrl = new AbortController();
|
| 1446 |
var _timeout = setTimeout(function(){ _abortCtrl.abort(); }, 30000);
|
|
@@ -1457,8 +1469,14 @@
|
|
| 1457 |
return;
|
| 1458 |
}
|
| 1459 |
var seg = data.matched_segment || '';
|
|
|
|
| 1460 |
var transText = seg.replace(/\s*【[^】]+】\s*$/, '').replace(/^\(/, '').replace(/\)$/, '');
|
|
|
|
|
|
|
|
|
|
| 1461 |
textEl.textContent = transText;
|
|
|
|
|
|
|
| 1462 |
} catch (err) {
|
| 1463 |
var msg = err.name === 'AbortError' ? 'انتهى وقت الانتظار' : 'حدث خطأ في الترجمة';
|
| 1464 |
textEl.innerHTML = '<span class="text-secondary">' + msg + '</span>';
|
|
@@ -1473,25 +1491,93 @@
|
|
| 1473 |
});
|
| 1474 |
}
|
| 1475 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1476 |
function applyQuranInlineResult() {
|
| 1477 |
if (!_quranInlineVerse) return;
|
| 1478 |
var editor = document.getElementById('editor-container');
|
| 1479 |
if (!editor) return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1480 |
if (typeof pushUndoState === 'function') pushUndoState();
|
| 1481 |
-
var
|
| 1482 |
-
var refHTML = _quranInlineRef ? ' <span class="quran-ref-inline">[' + esc(_quranInlineRef) + ']</span>' : '';
|
| 1483 |
var existing = editor.innerHTML;
|
| 1484 |
-
editor.innerHTML = existing + (existing ? '<br>' : '') +
|
| 1485 |
-
'<span class="quran-applied" contenteditable="false" data-quran="true">' +
|
| 1486 |
-
esc(_quranInlineVerse) + refHTML + '</span>';
|
| 1487 |
editor.dispatchEvent(new Event('input', { bubbles: true }));
|
| 1488 |
switchTab('write');
|
| 1489 |
-
if (typeof showToast === 'function') showToast('✓ تم إضافة ال
|
| 1490 |
}
|
| 1491 |
let _dialectResult = '';
|
|
|
|
| 1492 |
async function convertDialect() {
|
| 1493 |
var input = document.getElementById('dialect-input').value.trim();
|
| 1494 |
if (!input) { if (typeof showToast === 'function') showToast('الرجاء كتابة نص أولاً', 'warning'); return; }
|
|
|
|
| 1495 |
|
| 1496 |
var resultCard = document.getElementById('dialect-result-card');
|
| 1497 |
var resultDiv = document.getElementById('dialect-result');
|
|
@@ -1544,6 +1630,22 @@
|
|
| 1544 |
if (!editor) return;
|
| 1545 |
pushUndoState();
|
| 1546 |
var esc = function(t) { return t.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>'); };
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1547 |
editor.innerHTML = esc(_dialectResult);
|
| 1548 |
editor.dispatchEvent(new Event('input', { bubbles: true }));
|
| 1549 |
switchTab('write');
|
|
|
|
| 1 |
+
<!doctype html>
|
| 2 |
<html lang="ar" dir="rtl" class="h-full">
|
| 3 |
<head>
|
| 4 |
<meta charset="UTF-8">
|
|
|
|
| 968 |
</div>
|
| 969 |
<div id="quran-inline-translation" class="is-hidden p-4 rounded-xl" style="background:rgba(6,182,212,0.06); border:1px solid rgba(6,182,212,0.15);">
|
| 970 |
<p id="quran-inline-trans-text" style="font-size:18px; line-height:2; color:var(--color-text-primary); text-align:center;"></p>
|
| 971 |
+
<p id="quran-inline-trans-ref" class="text-sm text-center mt-2" style="color:#06b6d4; font-weight:600; display:none;"></p>
|
| 972 |
+
<div class="flex items-center justify-center gap-2 mt-3" id="quran-inline-trans-actions" style="display:none;">
|
| 973 |
+
<button onclick="copyQuranInlineTranslation()" class="quran-copy-btn" type="button" title="نسخ الترجمة">📋 نسخ</button>
|
| 974 |
+
<button onclick="applyQuranInlineTranslation()" class="quran-apply-btn" type="button">تطبيق الترجمة ✓</button>
|
| 975 |
+
</div>
|
| 976 |
</div>
|
| 977 |
</div>
|
| 978 |
</div>
|
|
|
|
| 1440 |
}
|
| 1441 |
}
|
| 1442 |
|
| 1443 |
+
let _quranInlineTransText = '';
|
| 1444 |
+
let _quranInlineTransRef = '';
|
| 1445 |
+
|
| 1446 |
async function translateQuranInline() {
|
| 1447 |
var lang = document.getElementById('quran-inline-lang').value;
|
| 1448 |
if (!lang || !_quranInlineQuery) return;
|
| 1449 |
var resultDiv = document.getElementById('quran-inline-translation');
|
| 1450 |
var textEl = document.getElementById('quran-inline-trans-text');
|
| 1451 |
+
var refEl = document.getElementById('quran-inline-trans-ref');
|
| 1452 |
+
var actionsEl = document.getElementById('quran-inline-trans-actions');
|
| 1453 |
textEl.innerHTML = '<span class="text-secondary">⏳ جاري الترجمة...</span>';
|
| 1454 |
+
if (refEl) refEl.style.display = 'none';
|
| 1455 |
+
if (actionsEl) actionsEl.style.display = 'none';
|
| 1456 |
resultDiv.classList.remove('is-hidden');
|
| 1457 |
var _abortCtrl = new AbortController();
|
| 1458 |
var _timeout = setTimeout(function(){ _abortCtrl.abort(); }, 30000);
|
|
|
|
| 1469 |
return;
|
| 1470 |
}
|
| 1471 |
var seg = data.matched_segment || '';
|
| 1472 |
+
var refMatch = seg.match(/【([^】]+)】/);
|
| 1473 |
var transText = seg.replace(/\s*【[^】]+】\s*$/, '').replace(/^\(/, '').replace(/\)$/, '');
|
| 1474 |
+
var transRef = refMatch ? refMatch[1] : '';
|
| 1475 |
+
_quranInlineTransText = transText;
|
| 1476 |
+
_quranInlineTransRef = transRef;
|
| 1477 |
textEl.textContent = transText;
|
| 1478 |
+
if (refEl && transRef) { refEl.textContent = '[' + transRef + ']'; refEl.style.display = ''; }
|
| 1479 |
+
if (actionsEl) actionsEl.style.display = '';
|
| 1480 |
} catch (err) {
|
| 1481 |
var msg = err.name === 'AbortError' ? 'انتهى وقت الانتظار' : 'حدث خطأ في الترجمة';
|
| 1482 |
textEl.innerHTML = '<span class="text-secondary">' + msg + '</span>';
|
|
|
|
| 1491 |
});
|
| 1492 |
}
|
| 1493 |
|
| 1494 |
+
function copyQuranInlineTranslation() {
|
| 1495 |
+
var text = (_quranInlineTransText || '') + (_quranInlineTransRef ? ' [' + _quranInlineTransRef + ']' : '');
|
| 1496 |
+
if (!text.trim()) return;
|
| 1497 |
+
navigator.clipboard.writeText(text).then(function() {
|
| 1498 |
+
if (typeof showToast === 'function') showToast('✓ تم نسخ الترجمة');
|
| 1499 |
+
});
|
| 1500 |
+
}
|
| 1501 |
+
|
| 1502 |
+
function _replaceQueryInEditor(newText, ref) {
|
| 1503 |
+
var editor = document.getElementById('editor-container');
|
| 1504 |
+
if (!editor) return false;
|
| 1505 |
+
var plain = editor.textContent || '';
|
| 1506 |
+
var query = _quranInlineQuery || '';
|
| 1507 |
+
var idx = plain.indexOf(query);
|
| 1508 |
+
if (idx === -1) return false;
|
| 1509 |
+
if (typeof pushUndoState === 'function') pushUndoState();
|
| 1510 |
+
var esc = function(t) { return t.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>'); };
|
| 1511 |
+
var before = plain.substring(0, idx);
|
| 1512 |
+
var after = plain.substring(idx + query.length);
|
| 1513 |
+
var refHTML = ref ? ' <span class="quran-ref-inline">[' + esc(ref) + ']</span>' : '';
|
| 1514 |
+
editor.innerHTML = esc(before) +
|
| 1515 |
+
'<span class="quran-applied" contenteditable="false" data-quran="true">' +
|
| 1516 |
+
esc(newText) + refHTML + '</span>' + esc(after);
|
| 1517 |
+
editor.focus();
|
| 1518 |
+
editor.dispatchEvent(new Event('input', { bubbles: true }));
|
| 1519 |
+
return true;
|
| 1520 |
+
}
|
| 1521 |
+
|
| 1522 |
function applyQuranInlineResult() {
|
| 1523 |
if (!_quranInlineVerse) return;
|
| 1524 |
var editor = document.getElementById('editor-container');
|
| 1525 |
if (!editor) return;
|
| 1526 |
+
// Try to replace original query text in editor
|
| 1527 |
+
if (_quranInlineQuery && _replaceQueryInEditor(_quranInlineVerse, _quranInlineRef)) {
|
| 1528 |
+
switchTab('write');
|
| 1529 |
+
if (typeof showToast === 'function') showToast('✓ تم استبدال النص بالنص القرآني المدقق');
|
| 1530 |
+
} else {
|
| 1531 |
+
// Fallback: append if original text not found in editor
|
| 1532 |
+
if (typeof pushUndoState === 'function') pushUndoState();
|
| 1533 |
+
var esc = function(t) { return t.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>'); };
|
| 1534 |
+
var refHTML = _quranInlineRef ? ' <span class="quran-ref-inline">[' + esc(_quranInlineRef) + ']</span>' : '';
|
| 1535 |
+
var existing = editor.innerHTML;
|
| 1536 |
+
editor.innerHTML = existing + (existing ? '<br>' : '') +
|
| 1537 |
+
'<span class="quran-applied" contenteditable="false" data-quran="true">' +
|
| 1538 |
+
esc(_quranInlineVerse) + refHTML + '</span>';
|
| 1539 |
+
editor.dispatchEvent(new Event('input', { bubbles: true }));
|
| 1540 |
+
switchTab('write');
|
| 1541 |
+
if (typeof showToast === 'function') showToast('✓ تم إضافة النص القرآني في المحرر');
|
| 1542 |
+
}
|
| 1543 |
+
}
|
| 1544 |
+
|
| 1545 |
+
function applyQuranInlineTranslation() {
|
| 1546 |
+
if (!_quranInlineTransText) return;
|
| 1547 |
+
var editor = document.getElementById('editor-container');
|
| 1548 |
+
if (!editor) return;
|
| 1549 |
+
if (_quranInlineQuery) {
|
| 1550 |
+
var plain = editor.textContent || '';
|
| 1551 |
+
var idx = plain.indexOf(_quranInlineQuery);
|
| 1552 |
+
if (idx !== -1) {
|
| 1553 |
+
if (typeof pushUndoState === 'function') pushUndoState();
|
| 1554 |
+
var esc = function(t) { return t.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>'); };
|
| 1555 |
+
var before = plain.substring(0, idx);
|
| 1556 |
+
var after = plain.substring(idx + _quranInlineQuery.length);
|
| 1557 |
+
var refHTML = _quranInlineTransRef ? ' <span class="quran-ref-inline">[' + esc(_quranInlineTransRef) + ']</span>' : '';
|
| 1558 |
+
editor.innerHTML = esc(before) + esc(_quranInlineTransText) + refHTML + esc(after);
|
| 1559 |
+
editor.focus();
|
| 1560 |
+
editor.dispatchEvent(new Event('input', { bubbles: true }));
|
| 1561 |
+
switchTab('write');
|
| 1562 |
+
if (typeof showToast === 'function') showToast('✓ تم تطبيق الترجمة في المحرر');
|
| 1563 |
+
return;
|
| 1564 |
+
}
|
| 1565 |
+
}
|
| 1566 |
+
// Fallback: append
|
| 1567 |
if (typeof pushUndoState === 'function') pushUndoState();
|
| 1568 |
+
var esc2 = function(t) { return t.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>'); };
|
|
|
|
| 1569 |
var existing = editor.innerHTML;
|
| 1570 |
+
editor.innerHTML = existing + (existing ? '<br>' : '') + esc2(_quranInlineTransText);
|
|
|
|
|
|
|
| 1571 |
editor.dispatchEvent(new Event('input', { bubbles: true }));
|
| 1572 |
switchTab('write');
|
| 1573 |
+
if (typeof showToast === 'function') showToast('✓ تم إضافة الترجمة في المحرر');
|
| 1574 |
}
|
| 1575 |
let _dialectResult = '';
|
| 1576 |
+
let _dialectInput = '';
|
| 1577 |
async function convertDialect() {
|
| 1578 |
var input = document.getElementById('dialect-input').value.trim();
|
| 1579 |
if (!input) { if (typeof showToast === 'function') showToast('الرجاء كتابة نص أولاً', 'warning'); return; }
|
| 1580 |
+
_dialectInput = input;
|
| 1581 |
|
| 1582 |
var resultCard = document.getElementById('dialect-result-card');
|
| 1583 |
var resultDiv = document.getElementById('dialect-result');
|
|
|
|
| 1630 |
if (!editor) return;
|
| 1631 |
pushUndoState();
|
| 1632 |
var esc = function(t) { return t.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>'); };
|
| 1633 |
+
// Try to replace original dialect text in editor
|
| 1634 |
+
if (_dialectInput) {
|
| 1635 |
+
var plain = editor.textContent || '';
|
| 1636 |
+
var idx = plain.indexOf(_dialectInput);
|
| 1637 |
+
if (idx !== -1) {
|
| 1638 |
+
var before = plain.substring(0, idx);
|
| 1639 |
+
var after = plain.substring(idx + _dialectInput.length);
|
| 1640 |
+
editor.innerHTML = esc(before) + esc(_dialectResult) + esc(after);
|
| 1641 |
+
editor.focus();
|
| 1642 |
+
editor.dispatchEvent(new Event('input', { bubbles: true }));
|
| 1643 |
+
switchTab('write');
|
| 1644 |
+
if (typeof showToast === 'function') showToast('✓ تم استبدال النص بالفصحى');
|
| 1645 |
+
return;
|
| 1646 |
+
}
|
| 1647 |
+
}
|
| 1648 |
+
// Fallback: replace all editor content
|
| 1649 |
editor.innerHTML = esc(_dialectResult);
|
| 1650 |
editor.dispatchEvent(new Event('input', { bubbles: true }));
|
| 1651 |
switchTab('write');
|