javascriptunicoderight-to-leftbidi

JavaScript: how to check if character is RTL?


How can I programmatically check if the browser treats some character as RTL in JavaScript?

Maybe creating some transparent DIV and looking at where text is placed?

A bit of context. Unicode 5.2 added Avestan alphabet support. So, if the browser has Unicode 5.2 support, it treats characters like U+10B00 as RTL (currently only Firefox does). Otherwise, it treats these characters as LTR, because this is the default.

How do I programmatically check this? I'm writing an Avestan input script and I want to override the bidi direction if the browser is too dumb. But, if browser does support Unicode, bidi settings shouldn't be overriden (since this will allow mixing Avestan and Cyrillic).

I currently do this:

var ua = navigator.userAgent.toLowerCase();

if (ua.match('webkit') || ua.match('presto') || ua.match('trident')) {
    var input = document.getElementById('orig');
    if (input) {
        input.style.direction = 'rtl';
        input.style.unicodeBidi = 'bidi-override';
    }
}

But, obviously, this would render script less usable after Chrome and Opera start supporting Unicode 5.2.


Solution

  • Thanks for your comments, but it seems I've done this myself:

    function is_script_rtl(t) {
        var d, s1, s2, bodies;
    
        //If the browser doesn’t support this, it probably doesn’t support Unicode 5.2
        if (!("getBoundingClientRect" in document.documentElement))
            return false;
    
        //Set up a testing DIV
        d = document.createElement('div');
        d.style.position = 'absolute';
        d.style.visibility = 'hidden';
        d.style.width = 'auto';
        d.style.height = 'auto';
        d.style.fontSize = '10px';
        d.style.fontFamily = "'Ahuramzda'";
        d.appendChild(document.createTextNode(t));
    
        s1 = document.createElement("span");
        s1.appendChild(document.createTextNode(t));
        d.appendChild(s1);
    
        s2 = document.createElement("span");
        s2.appendChild(document.createTextNode(t));
        d.appendChild(s2);
    
        d.appendChild(document.createTextNode(t));
    
        bodies = document.getElementsByTagName('body');
        if (bodies) {
            var body, r1, r2;
    
            body = bodies[0];
            body.appendChild(d);
            var r1 = s1.getBoundingClientRect();
            var r2 = s2.getBoundingClientRect();
            body.removeChild(d);
    
            return r1.left > r2.left;
        }
    
        return false;   
    }
    

    Example of using:

    Avestan in <script>document.write(is_script_rtl('𐬨𐬀𐬰𐬛𐬂') ? "RTL" : "LTR")</script>,
    Arabic is <script>document.write(is_script_rtl('العربية') ? "RTL" : "LTR")</script>,
    English is <script>document.write(is_script_rtl('English') ? "RTL" : "LTR")</script>.
    

    It seems to work. :)