--> jQuery(document).ready(function($) { /************************************************************ * CONFIGURATION ************************************************************/ const enableVirtualKeyboard = false; // ✅ Set true to enable virtual keyboard const keyboardLayouts = { en: 'english', dv: 'dv', ar: 'arabic', ur: 'urdu', fr: 'persian' }; /************************************************************ * RTL DETECTION ENGINE (rtlThis.js logic) ************************************************************/ const rtlThis = { options: { classPrefix: 'rtl-', template: '$&', scripts: { ara: { name: 'Arabic', regexp: /[\u0600-\u06FF\u0750-\u077F\uFB50-\uFDFF\uFE70-\uFEFF]+/g }, div: { name: 'Dhivehi', regexp: /[\u0780-\u07BF]+/g }, heb: { name: 'Hebrew', regexp: /[\u0590-\u05FF]+/g }, man: { name: 'Mandaic', regexp: /[\u0840-\u085F]+/g }, men: { name: 'Mende Kikakui', regexp: /[\u1E800-\u1E8DF]+/g }, nko: { name: "N'Ko", regexp: /[\u07C0-\u07FF]+/g }, syc: { name: 'Syriac', regexp: /[\u0700-\u074F]+/g }, tif: { name: 'Tifinagh', regexp: /[\u2D30-\u2D7F]+/g }, urd: { name: 'Urdu', regexp: /[\u0600-\u06FF]+/g } } }, run: function(selector, options) { const opts = $.extend(true, {}, this.options, options); const $elems = $(selector); $elems.each(function() { walkDOM(this, function(node) { const code = matchScript(node, opts.scripts); if (code) decorateText(node, opts.scripts[code], opts); }); }); function matchScript(node, scripts) { if (node.nodeType === Node.TEXT_NODE) { for (let code in scripts) { if (scripts[code].regexp.test(node.data)) { return code; } } } return false; } function decorateText(node, script, opts) { const html = node.textContent.replace(script.regexp, opts.template .replace('{{prefix}}', opts.classPrefix) .replace('{{code}}', script.name.toLowerCase()) .replace('$&', '$&')); if (html && node.parentNode) { node.parentNode.replaceChild( document.createRange().createContextualFragment(html), node ); } } function walkDOM(node, func) { func(node); node = node.firstChild; while (node) { walkDOM(node, func); node = node.nextSibling; } } } }; /************************************************************ * INPUT LANGUAGE HANDLER ************************************************************/ $('input[type="text"], textarea').on('focus', function() { const $field = $(this); const lang = $field.attr('lang') || 'en'; // Reset direction $field.attr('dir', 'ltr'); // Switch direction + placeholder switch (lang) { case 'dv': $field.attr('dir', 'rtl').attr('placeholder', 'ދިވެހި ބަހުން ލިޔުއްވާ...'); break; case 'ar': $field.attr('dir', 'rtl').attr('placeholder', 'Typing in Arabic...'); break; case 'ur': $field.attr('dir', 'rtl').attr('placeholder', 'Typing in Urdu...'); break; case 'fr': $field.attr('dir', 'rtl').attr('placeholder', 'Typing in Farsi...'); break; default: $field.attr('dir', 'ltr').attr('placeholder', 'Typing in English...'); } // Run RTL detection on this element (for mixed script support) rtlThis.run(this); // === OPTIONAL: Activate Virtual Keyboard === if (enableVirtualKeyboard && typeof $.keyboard === 'function') { if ($field.data('keyboard')) { $field.getkeyboard().destroy(); } const layout = keyboardLayouts[lang] || 'english'; $field.keyboard({ layout: layout, usePreview: false, autoAccept: true, alwaysOpen: false }); } }); // Also check all page content on load //rtlThis.run('body'); rtlThis.run('#dv-comment-form'); });