Mohamed Atef commited on
Commit
6018bdd
·
unverified ·
2 Parent(s): 7078e930ea3d3a

Merge pull request #10 from mohamedatef24/extention

Browse files
extension/content-inline.js CHANGED
@@ -634,6 +634,12 @@
634
 
635
  field.addEventListener('input', onFieldInput);
636
  field.addEventListener('keydown', onFieldKeydown);
 
 
 
 
 
 
637
  // FIX-20: Removed redundant 'keyup' listener (input event already fires on every change)
638
 
639
  if (BayanController.hasArabic(getFieldText(field))) {
@@ -645,6 +651,9 @@
645
  if (activeField) {
646
  activeField.removeEventListener('input', onFieldInput);
647
  activeField.removeEventListener('keydown', onFieldKeydown);
 
 
 
648
  // FIX-20: keyup listener no longer attached
649
  activeField.removeEventListener('scroll', syncOverlay);
650
  }
@@ -669,6 +678,24 @@
669
 
670
  const NON_CORRECTION_SOURCES = ['summarize', 'dialect', 'quran'];
671
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
672
  // Capture the field + selection range at right-click time. The context menu
673
  // flow always acts on the selected text, so we remember exactly what was
674
  // selected and splice the result into THAT range on write-back (Bug 2).
 
634
 
635
  field.addEventListener('input', onFieldInput);
636
  field.addEventListener('keydown', onFieldKeydown);
637
+ // Track the user's selection within the field so a later "apply" from the
638
+ // side panel can splice the result into exactly that range — even when the
639
+ // panel was opened via the FAB or was already open (not just right-click).
640
+ field.addEventListener('mouseup', onFieldSelect);
641
+ field.addEventListener('keyup', onFieldSelect);
642
+ field.addEventListener('select', onFieldSelect);
643
  // FIX-20: Removed redundant 'keyup' listener (input event already fires on every change)
644
 
645
  if (BayanController.hasArabic(getFieldText(field))) {
 
651
  if (activeField) {
652
  activeField.removeEventListener('input', onFieldInput);
653
  activeField.removeEventListener('keydown', onFieldKeydown);
654
+ activeField.removeEventListener('mouseup', onFieldSelect);
655
+ activeField.removeEventListener('keyup', onFieldSelect);
656
+ activeField.removeEventListener('select', onFieldSelect);
657
  // FIX-20: keyup listener no longer attached
658
  activeField.removeEventListener('scroll', syncOverlay);
659
  }
 
678
 
679
  const NON_CORRECTION_SOURCES = ['summarize', 'dialect', 'quran'];
680
 
681
+ // Snapshot the active field's selection whenever the user changes it. We keep
682
+ // the LAST non-empty selection so that when focus later moves to the side
683
+ // panel (which collapses the field's visible selection) we still know which
684
+ // range the user meant to replace. A collapsed selection does NOT clear the
685
+ // snapshot — only a real edit (handled in onFieldInput) or a fresh write does.
686
+ function onFieldSelect(e) {
687
+ const field = e && e.currentTarget;
688
+ if (!field) return;
689
+ const tag = field.tagName.toLowerCase();
690
+ if (tag !== 'textarea' && tag !== 'input') return;
691
+ const start = field.selectionStart;
692
+ const end = field.selectionEnd;
693
+ if (typeof start === 'number' && typeof end === 'number' && start !== end) {
694
+ pendingSelection = { field, type: 'input', start, end };
695
+ lastInteractedField = field;
696
+ }
697
+ }
698
+
699
  // Capture the field + selection range at right-click time. The context menu
700
  // flow always acts on the selected text, so we remember exactly what was
701
  // selected and splice the result into THAT range on write-back (Bug 2).
extension/sidepanel/sidepanel.html CHANGED
@@ -274,9 +274,14 @@
274
  <div class="sp-result is-hidden" id="quran-translation-result" style="margin-top:8px;">
275
  <div class="sp-result-header">
276
  <span>الترجمة</span>
277
- <button class="sp-btn-icon" id="btn-copy-quran-translation" title="نسخ الترجمة">
278
- <svg width="14" height="14" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"/></svg>
279
- </button>
 
 
 
 
 
280
  </div>
281
  <div class="sp-result-text" id="quran-translation-text" dir="auto"></div>
282
  <div class="sp-summary-meta" id="quran-translation-ref"></div>
 
274
  <div class="sp-result is-hidden" id="quran-translation-result" style="margin-top:8px;">
275
  <div class="sp-result-header">
276
  <span>الترجمة</span>
277
+ <div class="sp-result-actions">
278
+ <button class="sp-btn-icon" id="btn-apply-quran-translation" title="تطبيق في الصفحة">
279
+ <svg width="14" height="14" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
280
+ </button>
281
+ <button class="sp-btn-icon" id="btn-copy-quran-translation" title="نسخ الترجمة">
282
+ <svg width="14" height="14" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"/></svg>
283
+ </button>
284
+ </div>
285
  </div>
286
  <div class="sp-result-text" id="quran-translation-text" dir="auto"></div>
287
  <div class="sp-summary-meta" id="quran-translation-ref"></div>
extension/sidepanel/sidepanel.js CHANGED
@@ -499,6 +499,7 @@ document.addEventListener('DOMContentLoaded', () => {
499
  const quranTranslationText = document.getElementById('quran-translation-text');
500
  const quranTranslationRef = document.getElementById('quran-translation-ref');
501
  const btnCopyQuranTranslation = document.getElementById('btn-copy-quran-translation');
 
502
  let lastQuranQuery = '';
503
 
504
  // Parse the API's "(verse text) 【surah:ayah】" segment into {text, ref}.
@@ -581,6 +582,16 @@ document.addEventListener('DOMContentLoaded', () => {
581
  });
582
  }
583
 
 
 
 
 
 
 
 
 
 
 
584
  btnCopyQuran.addEventListener('click', () => {
585
  navigator.clipboard.writeText(quranText.textContent || '')
586
  .then(() => showToast('✓ تم النسخ'))
 
499
  const quranTranslationText = document.getElementById('quran-translation-text');
500
  const quranTranslationRef = document.getElementById('quran-translation-ref');
501
  const btnCopyQuranTranslation = document.getElementById('btn-copy-quran-translation');
502
+ const btnApplyQuranTranslation = document.getElementById('btn-apply-quran-translation');
503
  let lastQuranQuery = '';
504
 
505
  // Parse the API's "(verse text) 【surah:ayah】" segment into {text, ref}.
 
582
  });
583
  }
584
 
585
+ // Apply the translated verse straight into the page field (Req 2).
586
+ // Routed as 'quran' so the content script suppresses correction re-analysis.
587
+ if (btnApplyQuranTranslation) {
588
+ btnApplyQuranTranslation.addEventListener('click', () => {
589
+ const text = (quranTranslationText.textContent || '').trim();
590
+ if (!text) { showToast('لا توجد ترجمة للتطبيق'); return; }
591
+ writeBackToPage(text, 'auto', 'quran');
592
+ });
593
+ }
594
+
595
  btnCopyQuran.addEventListener('click', () => {
596
  navigator.clipboard.writeText(quranText.textContent || '')
597
  .then(() => showToast('✓ تم النسخ'))