Arabic Keyboard Remapper

Maps English keyboard to Arabic letters (QWERTY to Arabic layout)

이 스크립트를 설치하려면 Tampermonkey, Greasemonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

You will need to install an extension such as Tampermonkey to install this script.

이 스크립트를 설치하려면 Tampermonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Userscripts와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 유저 스크립트 관리자 확장 프로그램이 필요합니다.

(이미 유저 스크립트 관리자가 설치되어 있습니다. 설치를 진행합니다!)

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

(이미 유저 스타일 관리자가 설치되어 있습니다. 설치를 진행합니다!)

// ==UserScript==
// @name         Arabic Keyboard Remapper
// @namespace    http://tampermonkey.net/
// @version      5.1
// @description  Maps English keyboard to Arabic letters (QWERTY to Arabic layout)
// @author       Your Name
// @match        *://*/*
// @grant        none
// @run-at       document-start
// ==/UserScript==

(function() {
    'use strict';

    console.log('===========================================');
    console.log('ARABIC KEYBOARD SCRIPT STARTING...');
    console.log('===========================================');

    // الخريطة الرئيسية - تخطيط لوحة المفاتيح القياسي
    var map = {
        // Row 1
        '`': 'ذ', '~': 'ّ',
        '1': '١', '!': '!',
        '2': '٢', '@': '"',
        '3': '٣', '#': '٣',
        '4': '٤', '$': '٤',
        '5': '٥', '%': '٥',
        '6': '٦', '^': '^',
        '7': '٧', '&': '&',
        '8': '٨', '*': '*',
        '9': '٩', '(': '(',
        '0': '٠', ')': ')',
        '-': '-', '_': '_',
        '=': '=', '+': '+',
        
        // Row 2 (QWERTY)
        'q': 'ض', 'Q': 'َ',      // Fatha
        'w': 'ص', 'W': 'ً',      // Fathatan
        'e': 'ث', 'E': 'ُ',      // Damma
        'r': 'ق', 'R': 'ٌ',      // Dammatan
        't': 'ف', 'T': 'لإ',     // Lam + Alef with Hamza below
        'y': 'غ', 'Y': 'إ',      // Alef with Hamza below
        'u': 'ع', 'U': '`',      // Hamza
        'i': 'ه', 'I': 'ِ',      // Kasra
        'o': 'خ', 'O': 'ٍ',      // Kasratan
        'p': 'ح', 'P': '؛',      // Arabic semicolon
        '[': 'ج', '{': '}',
        ']': 'د', '}': '{',
        '\\': '\\', '|': '|',
        
        // Row 3 (ASDF)
        'a': 'ش', 'A': 'ّ',      // Shadda
        's': 'س', 'S': 'ْ',      // Sukun
        'd': 'ي', 'D': ']',
        'f': 'ب', 'F': '[',
        'g': 'ل', 'G': 'لأ',     // Lam + Alef with Hamza above
        'h': 'ا', 'H': 'أ',      // Alef with Hamza above
        'j': 'ت', 'J': 'ـ',      // Tatweel
        'k': 'ن', 'K': '،',      // Arabic comma
        'l': 'م', 'L': '/',
        ';': 'ك', ':': ':',
        "'": 'ط', '"': '"',
        
        // Row 4 (ZXCV)
        'z': 'ئ', 'Z': '~',
        'x': 'ء', 'X': 'ْ',      // Sukun (alternative)
        'c': 'ؤ', 'C': '}',
        'v': 'ر', 'V': '{',
        'b': 'لا', 'B': 'لآ',    // Lam + Alef with Madda
        'n': 'ى', 'N': 'آ',      // Alef with Madda
        'm': 'ة', 'M': "'",
        ',': 'و', '<': ',',
        '.': 'ز', '>': '.',
        '/': 'ظ', '?': '؟'      // Arabic question mark
    };

    console.log('Map created with ' + Object.keys(map).length + ' entries');

    // قائمة بأنواع المدخلات المسموح بها
    var allowedInputTypes = [
        'text', 'password', 'search', 'email', 'url', 'tel', 'number'
    ];

    function isEditableElement(element) {
        // التحقق مما إذا كان العنصر قابل للتحرير
        if (element.isContentEditable) {
            return true;
        }
        
        if (element.tagName === 'TEXTAREA') {
            return true;
        }
        
        if (element.tagName === 'INPUT') {
            var type = element.type.toLowerCase();
            return allowedInputTypes.includes(type);
        }
        
        // للعناصر الأخرى مثل div[contenteditable="true"]
        if (element.hasAttribute('contenteditable') && 
            element.getAttribute('contenteditable').toLowerCase() === 'true') {
            return true;
        }
        
        return false;
    }

    function handleKeyDown(e) {
        // تجاهل التركيبات الخاصة (Ctrl, Alt, Win/Command)
        if (e.ctrlKey || e.altKey || e.metaKey) {
            return;
        }
        
        // تجاهل المفاتيح الوظيفية (F1-F12)
        if (e.key.length > 1 && ![' ', 'Enter', 'Tab'].includes(e.key)) {
            return;
        }

        var element = e.target;
        
        // التحقق مما إذا كان العنصر قابل للتحرير
        if (!isEditableElement(element)) {
            return;
        }
        
        // الحصول على المفتاح المضغوط
        var key = e.key;
        
        // التحقق مما إذا كان المفتاح موجود في الخريطة
        if (map.hasOwnProperty(key)) {
            e.preventDefault();
            e.stopImmediatePropagation();
            
            var arabicChar = map[key];
            
            if (element.isContentEditable || element.hasAttribute('contenteditable')) {
                // للعناصر القابلة للتحرير (contentEditable)
                try {
                    document.execCommand('insertText', false, arabicChar);
                } catch (error) {
                    // Fallback يدوي
                    var selection = window.getSelection();
                    if (selection.rangeCount > 0) {
                        var range = selection.getRangeAt(0);
                        range.deleteContents();
                        var textNode = document.createTextNode(arabicChar);
                        range.insertNode(textNode);
                        range.setStartAfter(textNode);
                        range.setEndAfter(textNode);
                        selection.removeAllRanges();
                        selection.addRange(range);
                    }
                }
            } else {
                // لحقول الإدخال العادية (input, textarea)
                var start = element.selectionStart;
                var end = element.selectionEnd;
                var value = element.value;
                
                // استبدال النص المحدد أو إدراج الحرف الجديد
                element.value = value.substring(0, start) + arabicChar + value.substring(end);
                
                // تحديث موضع المؤشر
                element.selectionStart = element.selectionEnd = start + arabicChar.length;
                
                // تشغيل الأحداث المطلوبة للتطبيقات الحديثة
                var events = ['input', 'change', 'keyup'];
                events.forEach(function(eventName) {
                    var event = new Event(eventName, {
                        bubbles: true,
                        cancelable: true
                    });
                    element.dispatchEvent(event);
                });
            }
            
            console.debug('Mapped: "' + key + '" → "' + arabicChar + '"');
        }
    }

    // إضافة المستمع للحدث
    document.addEventListener('keydown', handleKeyDown, {
        capture: true,
        passive: false
    });

    // دالة لتفعيل/تعطيل البرنامج النصي
    function toggleScript() {
        var isEnabled = !window.arabicKeyboardEnabled;
        window.arabicKeyboardEnabled = isEnabled;
        
        if (isEnabled) {
            document.addEventListener('keydown', handleKeyDown, {
                capture: true,
                passive: false
            });
            console.log('Arabic Keyboard: ENABLED');
        } else {
            document.removeEventListener('keydown', handleKeyDown, true);
            console.log('Arabic Keyboard: DISABLED');
        }
        
        // إشعار بصري مؤقت
        showNotification('Arabic Keyboard: ' + (isEnabled ? 'ENABLED' : 'DISABLED'));
    }

    // دالة لعرض إشعار
    function showNotification(message) {
        var notification = document.createElement('div');
        notification.style.cssText = `
            position: fixed;
            top: 20px;
            right: 20px;
            background: #4CAF50;
            color: white;
            padding: 15px 20px;
            border-radius: 5px;
            z-index: 10000;
            font-family: Arial, sans-serif;
            font-size: 14px;
            box-shadow: 0 4px 6px rgba(0,0,0,0.1);
            transition: opacity 0.3s;
        `;
        notification.textContent = message;
        document.body.appendChild(notification);
        
        setTimeout(function() {
            notification.style.opacity = '0';
            setTimeout(function() {
                if (notification.parentNode) {
                    notification.parentNode.removeChild(notification);
                }
            }, 300);
        }, 2000);
    }

    // إضافة اختصار لوحة المفاتيح لتفعيل/تعطيل البرنامج (Ctrl+Alt+A)
    document.addEventListener('keydown', function(e) {
        if (e.ctrlKey && e.altKey && e.key.toLowerCase() === 'a') {
            e.preventDefault();
            toggleScript();
        }
    });

    // تهيئة الحالة
    window.arabicKeyboardEnabled = true;

    console.log('===========================================');
    console.log('ARABIC KEYBOARD IS NOW ACTIVE!');
    console.log('Usage: Type in any text field to use Arabic keyboard mapping');
    console.log('Toggle: Press Ctrl+Alt+A to enable/disable');
    console.log('===========================================');

})();