Search code examples
unicodeckeditorarabic-supporturdu

How to force cursive display in ckeditor while typing


<!DOCTYPE html>
<html>
  <head>
    <script src="http://cdn.ckeditor.com/4.6.2/standard/ckeditor.js"></script>
  </head>

  <body>
	<textarea name="editorUrdu"></textarea>
	<script>
		CKEDITOR.plugins.addExternal( 'easykeymap', '/ckeditor/plugins/easykeymap', 'plugin.js' );
		CKEDITOR.replace( 'editorUrdu',{
			extraPlugins: 'easykeymap',
			contentsLangDirection: 'rtl'
		});
	</script>
  </body>
</html>

/**
 * This work is mine, and yours. You can modify it as you wish.
 * @Author: Roni Saha<[email protected]>
 *
 * This source file is subject to the MIT license that is bundled
 * with this source code in the file LICENSE.
 */

CKEDITOR.plugins.add('easykeymap',
    {
        requires : ['wysiwygarea'],
        init: function (editor) {

            //var keyMaps = CKEDITOR.tools.extend({}, editor.config.easykeymaps || {}, true);
            //Not using keymap specification from config variables, but using internally defined ones from param below

            function isRegisteredKeystroke(code) {
                if(typeof editor.keystrokeHandler.keystrokes[code] != 'undefined') {
                    console.warn("the keystroke : " + code + " is being attached to another event")
                    return true;
                }
                return false;
            }
            
            var sm1 = [];   var en1 = [];
            sm1[192]="؏";   en1[192]="~";
            sm1[49]="۱";    en1[49]="1";
            sm1[50]="۲";    en1[50]="2";
            sm1[51]="۳";    en1[51]="3";
            sm1[52]="۴";    en1[52]="4";
            sm1[53]="۵";    en1[53]="5";
            sm1[54]="۶";    en1[54]="6";
            sm1[55]="۷";    en1[55]="7";
            sm1[56]="۸";    en1[56]="8";
            sm1[57]="۹";    en1[57]="9";
            sm1[48]="۰";    en1[48]="0";
            sm1[189]="-";   en1[189]="-";
            sm1[187]="=";   en1[187]="=";
            //sm1[8]="";    en1[8]="";//BACKSPACE
                
            var sm2 = [];   var en2 = [];
            sm2[9]="";      en2[9]="";//TAB
            sm2[81]="ق";    en2[81]="Q";
            sm2[87]="و";    en2[87]="W";
            sm2[69]="ع";    en2[69]="E";
            sm2[82]="ر";    en2[82]="R";
            sm2[84]="ت";    en2[84]="T";
            sm2[89]="ے";    en2[89]="Y";
            sm2[85]="ء";    en2[85]="U";
            sm2[73]="ی";    en2[73]="I";
            sm2[79]="ہ";    en2[79]="O";
            sm2[80]="پ";    en2[80]="P";
            sm2[219]="'";   en2[219]="{";
            sm2[221]="ﷲ";   en2[221]="}";
            sm2[220]="÷";   en2[220]="\\";
            
            var sm3 = [];   var en3 = [];
            //sm3[20]="";   en3[20]="";//CAPSLOCK
            sm3[65]="ا";     en3[65]="A";
            sm3[83]="س";    en3[83]="S";
            sm3[68]="د";     en3[68]="D";
            sm3[70]="ف";    en3[70]="F";
            sm3[71]="گ";    en3[71]="G";
            sm3[72]="ح";    en3[72]="H";
            sm3[74]="ج";    en3[74]="J";
            sm3[74]="ک";    en3[75]="K";
            sm3[76]="ل";    en3[76]="L";
            sm3[186]="؛";    en3[186]=":";
            sm3[222]=",";   en3[222]="\"";
            sm3[13]="";     en3[13]="";//ENTER
            
            var sm4 = [];   var en4 = [];
            //sm4[16]="";   en4[16]="";//SHIFT
            sm4[90]="ز";    en4[90]="Z";
            sm4[88]="ش";    en4[88]="X";
            sm4[67]="چ";    en4[67]="C";
            sm4[86]="ط";    en4[86]="V";
            sm4[66]="ب";    en4[66]="B";
            sm4[78]="ن";    en4[78]="N";
            sm4[77]="م";    en4[77]="M";
            sm4[188]="،";    en4[188]="<";
            sm4[190]="۔";    en4[190]=">";
            sm4[191]="/";   en4[191]="?";
            sm4[16]="";     en4[16]="";//SHIFT
                
            var keyBoard = {};
            keyBoard.Row1 = { "sm" : sm1, "en" : en1 };
            keyBoard.Row2 = { "sm" : sm2, "en" : en2 };
            keyBoard.Row3 = { "sm" : sm3, "en" : en3 };
            keyBoard.Row4 = { "sm" : sm4, "en" : en4 };

            function getMappedCharacter(code) {
                console.info(code);
                if (typeof keyBoard.Row1.sm[code] != 'undefined')
                    return keyBoard.Row1.sm[code] 
                else if (typeof keyBoard.Row2.sm[code] != 'undefined')
                    return keyBoard.Row2.sm[code]
                else if (typeof keyBoard.Row3.sm[code] != 'undefined')
                    return keyBoard.Row3.sm[code]
                else if (typeof keyBoard.Row4.sm[code] != 'undefined')
                    return keyBoard.Row4.sm[code]
                else
                    return false;
            }

            editor.on( 'key', function( event ) {
				var t = event.target;
                var mappedCode = getMappedCharacter(event.data.keyCode);
                if (mappedCode !== false && !isRegisteredKeystroke(event.data.keyCode)) {

                    event.cancel();

                    if(typeof mappedCode == 'function') {
                        return mappedCode.call(editor, editor);
                    }
                    editor.insertText(mappedCode);
                }
            } );
        }
    });

I'm using ckeditor for allowing my users to input Urdu text. Like Arabic, Urdu is cursive, and uses distinct ligatures when joined.

I'm using the

 editor.on( 'key', function( event )) 

event to intercept the

event.data.keyCode 

and replace it using

 editor.insertText() 

function.

So, e.g. if the user types L and A, I replace it with the Urdu

ا (U+0627) 

and

ل (U+0644). 

Now, after being typed, they both appear as distinct characters, separate from each other. I can press space, or enter, and they both remain as they are. But I would like them to be replaced with their proper equivalent ligature ﻻ which is FEFB in this unicode chart

I see that ckeditor automatically correct this if I switch to Source view. There, inside the <p> block, it shows the separate, disjointed letter's already replace with proper cursive ligature. And it keeps it that way when I switch back from Source view. But whatever is causing this to happen, how can I trigger that to happen while typing?

Attaching images also.

After typing After typing After going to source view After going to source view After returning from source view After returning from source view


Solution

  • When ever you type L and A , editor.insertText() is just append it as two separate stings, instead of combining into one.

    <p>"ل"
         "ا"
    <br>
    </p>
    

    that why its not producing desired output.

    Added these two line

    var $pTag = editor.getSelection().getRanges()[0].startContainer.$; // accessing the p tag
    $pTag.innerText = $pTag.innerText+mappedCode; // modifing the inner text
    

    replacing

    editor.insertText(mappedCode); // in editor.on( 'key', function( event )
    

    will output as "لا"

    above fix has some issues to deal with like linebeak(new line)

    Updated

    replace the below snippet

    var $pTag = editor.getSelection().getRanges()[0].startContainer.$;
    var innerText =$pTag.innerText; // accessing the p tag data
    $pTag.innerText = ""; // removing the existing data
    editor.insertHtml(innerText+mappedCode); // concat with new string
    

    with

    editor.insertText(mappedCode); // in editor.on( 'key', function( event )
    

    Example: codepen