mesdan
Version:
Latinî mesdan ile Osmanî metin yazmak için hazırlanmış bir alettir.
215 lines (214 loc) • 10.4 kB
JavaScript
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,
};
};