UNPKG

mesdan

Version:

Latinî mesdan ile Osmanî metin yazmak için hazırlanmış bir alettir.

215 lines (214 loc) 10.4 kB
import { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react'; import { harfBüyükMü } from '../aletler/harf-buyuk-mu'; import { hazırlaAlemMevkisini, hazırlaAlemMevkisiniMenzilli } from '../nevi/alem-mevkisi'; import { TadiliMetinEmri } from '../nevi/tadili-metin-emri'; import { Talimat_MetniTadilEt } from '../nuve/kanca/tadil-et-metni'; export const useMesdan = ({ ibtidaiMetin = '', tekSatırMı, latiniMi: ibtidaiLatiniMi = false, aramaTalepEdilince, metin: metinHarici, tayinMetin: tayinMetinHarici, }) => { const [metinDahili, tayinMetinDahili] = useState(ibtidaiMetin); const [latiniMi, tayinLatiniMi] = useState(ibtidaiLatiniMi); const metinSahasıİması = useRef(null); const [alemMevkisi, tayinAlemMevkisi] = useState(hazırlaAlemMevkisini(ibtidaiMetin.length)); const idareHariçteMi = metinHarici !== undefined && tayinMetinHarici !== undefined; const metin = idareHariçteMi ? metinHarici : metinDahili; const tayinMetin = useCallback((yeniMetin) => { if (idareHariçteMi) { tayinMetinHarici(yeniMetin); } else { tayinMetinDahili(yeniMetin); } }, [idareHariçteMi, tayinMetinHarici]); const aramaTalepEdilinceRef = useRef(aramaTalepEdilince); useEffect(() => { aramaTalepEdilinceRef.current = aramaTalepEdilince; }, [aramaTalepEdilince]); const alemMevkisiEvveli = useRef({ baş: 0, son: 0 }); const handleKeydown = useCallback(async (hadise) => { const metinSahası = metinSahasıİması.current; if (!metinSahası) return; hadise.preventDefault(); hadise.stopPropagation(); const mevzuMetin = metinSahası.value; const alemMevkisi = hazırlaAlemMevkisiniMenzilli(metinSahası.selectionStart || 0, metinSahası.selectionEnd || 0); const mesHadisesi = { latiniHarf: hadise.key, shiftBasılıMı: hadise.shiftKey, altBasılıMı: hadise.altKey, capsLockBasılıMı: harfBüyükMü(hadise.key), }; let tadiliMetinEmri = TadiliMetinEmri.EKLE; if (tekSatırMı && hadise.key === 'Enter') { tadiliMetinEmri = TadiliMetinEmri.ARA; aramaTalepEdilinceRef.current?.(metin); return; } else if (!tekSatırMı && hadise.key === 'Enter') { tadiliMetinEmri = TadiliMetinEmri.EKLE; mesHadisesi.latiniHarf = '\n'; } else if (hadise.key === 'Delete') tadiliMetinEmri = TadiliMetinEmri.SİL_AHİRDEN; else if (hadise.key === 'Backspace') tadiliMetinEmri = TadiliMetinEmri.SİL_EVVELDEN; else if (hadise.key === 'ArrowRight') tadiliMetinEmri = TadiliMetinEmri.ALEM_SAĞA; else if (hadise.key === 'ArrowLeft') tadiliMetinEmri = TadiliMetinEmri.ALEM_SOLA; else if (hadise.key === 'ArrowUp') tadiliMetinEmri = TadiliMetinEmri.ALEM_ÜSTE; else if (hadise.key === 'ArrowDown') tadiliMetinEmri = TadiliMetinEmri.ALEM_ALTA; else if (hadise.ctrlKey && !hadise.altKey) { // !hadise.altKey guarantees this doesn't block AltGr keys (which produce @, #, etc.) if (hadise.key.toLowerCase() === 'c') tadiliMetinEmri = TadiliMetinEmri.BELLE; else if (hadise.key.toLowerCase() === 'x') tadiliMetinEmri = TadiliMetinEmri.KOPAR; else if (hadise.key.toLowerCase() === 'v') tadiliMetinEmri = TadiliMetinEmri.YERLE; else tadiliMetinEmri = TadiliMetinEmri.BOŞ; } else if (['Shift', 'Alt', 'AltGraph', 'Meta', 'Tab', 'CapsLock', 'Dead'].includes(hadise.key)) { tadiliMetinEmri = TadiliMetinEmri.BOŞ; } const netice = await Talimat_MetniTadilEt(mevzuMetin, alemMevkisi, tadiliMetinEmri, mesHadisesi, true); tayinAlemMevkisi(netice.alemMevkisiTadilSonrası); tayinMetin(netice.metinTadilSonrası); }, [metin, tekSatırMı, tayinMetin]); const handlePaste = useCallback(async (hadise) => { const metinSahası = metinSahasıİması.current; if (!metinSahası) return; hadise.preventDefault(); const mevzuMetin = metinSahası.value; const alemMevkisi = hazırlaAlemMevkisiniMenzilli(metinSahası.selectionStart || 0, metinSahası.selectionEnd || 0); const netice = await Talimat_MetniTadilEt(mevzuMetin, alemMevkisi, TadiliMetinEmri.YERLE, { latiniHarf: '', shiftBasılıMı: false, altBasılıMı: false, capsLockBasılıMı: false }, true); tayinAlemMevkisi(netice.alemMevkisiTadilSonrası); tayinMetin(netice.metinTadilSonrası); }, [tayinMetin]); const handleBeforeInput = useCallback((hadise) => { const metinSahası = metinSahasıİması.current; if (!metinSahası) return; alemMevkisiEvveli.current.baş = metinSahası.selectionStart || 0; alemMevkisiEvveli.current.son = metinSahası.selectionEnd || 0; }, []); const handleInput = useCallback(async (hadise) => { const metinSahası = metinSahasıİması.current; if (!metinSahası) return; const harf = hadise.data || ''; const mesHadisesi = { latiniHarf: harf.replace('. ', ' '), shiftBasılıMı: false, altBasılıMı: false, capsLockBasılıMı: harfBüyükMü(harf), }; let tadiliMetinEmri = TadiliMetinEmri.EKLE; if (!tekSatırMı && hadise.inputType === 'insertLineBreak') { mesHadisesi.latiniHarf = '\n'; } else if (hadise.inputType === 'deleteContentBackward') { tadiliMetinEmri = TadiliMetinEmri.SİL_EVVELDEN; } else if (hadise.inputType === 'deleteByCut') { tadiliMetinEmri = TadiliMetinEmri.KOPAR; } else if (hadise.inputType === 'insertFromPaste') { tadiliMetinEmri = TadiliMetinEmri.YERLE; } const mevzuMetin = metin; const alemMevkisi = hazırlaAlemMevkisiniMenzilli(alemMevkisiEvveli.current.baş, alemMevkisiEvveli.current.son); const netice = await Talimat_MetniTadilEt(mevzuMetin, alemMevkisi, tadiliMetinEmri, mesHadisesi, false); tayinAlemMevkisi(netice.alemMevkisiTadilSonrası); tayinMetin(netice.metinTadilSonrası); }, [metin, tekSatırMı, tayinMetin]); const handleSelect = useCallback(() => { const metinSahası = metinSahasıİması.current; if (!metinSahası) return; tayinAlemMevkisi(hazırlaAlemMevkisiniMenzilli(metinSahası.selectionStart || 0, metinSahası.selectionEnd || 0)); }, []); useEffect(() => { const metinSahası = metinSahasıİması.current; if (!metinSahası) { return; } // Listener for "Latin" (normal) mode const handleNativeInput = (e) => { const target = e.target; tayinMetin(target.value); }; const handleNativeKeydown = (e) => { if (e instanceof KeyboardEvent && e.key === 'Enter' && tekSatırMı) { e.preventDefault(); aramaTalepEdilinceRef.current?.(metin); } }; // Listeners for your custom mode const keydownListener = (e) => handleKeydown(e); const pasteListener = (e) => handlePaste(e); const beforeInputListener = (e) => handleBeforeInput(e); const inputListener = (e) => handleInput(e); if (latiniMi) { // --- LATIN MODE --- metinSahası.setAttribute('spellcheck', 'true'); metinSahası.addEventListener('input', handleNativeInput); metinSahası.addEventListener('keydown', handleNativeKeydown); } else { // --- CUSTOM MODE --- metinSahası.setAttribute('spellcheck', 'false'); metinSahası.setAttribute('autocorrect', 'off'); metinSahası.setAttribute('autocapitalize', 'off'); metinSahası.setAttribute('autocomplete', 'off'); if (tekSatırMı) { metinSahası.setAttribute('enterkeyhint', 'done'); } if (window.matchMedia('(pointer: coarse)').matches) { metinSahası.addEventListener('beforeinput', beforeInputListener); metinSahası.addEventListener('input', inputListener); } else { metinSahası.addEventListener('keydown', keydownListener); metinSahası.addEventListener('paste', pasteListener); } metinSahası.addEventListener('select', handleSelect, { passive: true }); } return () => { // Remove Latin mode listeners metinSahası.removeEventListener('input', handleNativeInput); metinSahası.removeEventListener('keydown', handleNativeKeydown); // Remove Custom mode listeners metinSahası.removeEventListener('beforeinput', beforeInputListener); metinSahası.removeEventListener('input', inputListener); metinSahası.removeEventListener('keydown', keydownListener); metinSahası.removeEventListener('paste', pasteListener); metinSahası.removeEventListener('select', handleSelect); }; }, [metin, latiniMi, tekSatırMı, handleKeydown, handlePaste, handleBeforeInput, handleInput, handleSelect, tayinMetin]); useLayoutEffect(() => { const metinSahası = metinSahasıİması.current; if (metinSahası && !latiniMi) { const { başMevki, sonMevki } = alemMevkisi; if (metinSahası.selectionStart !== başMevki || metinSahası.selectionEnd !== sonMevki) { if (başMevki <= metinSahası.value.length && sonMevki <= metinSahası.value.length) { metinSahası.setSelectionRange(başMevki, sonMevki); } } } }, [metin, latiniMi, alemMevkisi]); const tebdilMetin = useCallback((yeniMetin) => { tayinMetin(yeniMetin); tayinAlemMevkisi(hazırlaAlemMevkisini(yeniMetin.length)); }, [tayinMetin]); return { metinSahasıİması, metin, tebdilMetin, latiniMi, tebdilLatiniMi: tayinLatiniMi, }; };