Ticket #3698: 3698.patch

File 3698.patch, 38.8 KB (added by Wiktor Walc, 11 years ago)
  • _source/includes/cklangtool.js

     
    1111        languageDir : "",
    1212        templateFile : "",
    1313        operation : "default",
     14        EOL : '\r\n',
    1415        /**
    1516         * Holds the content of en.js language file where strings are replaced with
    1617         * special placeholders: #ckeditor_translation.placeholder.key#.
    1718         */
    1819        template : "",
    1920        path : "",
    20        
     21        header : "Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.\r\nFor licensing, see LICENSE.html or http://ckeditor.com/license",
     22
    2123        load : function( className )
    2224        {
    2325                if ( CKLANGTOOL.isCompiled )
     
    3234
    3335                        load( CKLANGTOOL.path + path );
    3436                }
    35         }       
     37        }
    3638};
    3739
    3840/**
     
    7173                        for ( var i in scope )
    7274                        {
    7375                                if ( i != "CKEDITOR" )
    74                                         return { 'languageCode' : languageCode, 'translation' : scope[i] };
     76                                        return { 'languageCode' : languageCode, 'translation' : scope[i], 'type' : 'other' };
    7577                        }
    7678                }
    7779                else
     
    8284                        for ( var i in scope.CKEDITOR.lang )
    8385                        {
    8486                                languageCode = i;
    85                                 return { 'languageCode' : languageCode, 'translation' : scope.CKEDITOR.lang[i] };
     87                                return { 'languageCode' : languageCode, 'translation' : scope.CKEDITOR.lang[i], 'type' : 'CKEditor' };
    8688                        }
    8789                }
    8890        }
     
    9698{
    9799        CKLANGTOOL.translator = function()
    98100        {
    99                 CKLANGTOOL.englishTranslation =
    100                 {};
     101                CKLANGTOOL.englishTranslation = {};
    101102        };
    102103
    103104        /**
     
    123124                }
    124125                catch ( e )
    125126                {
    126                         throw ("Error in " + file.getAbsolutePath() + "\n" + "Line: " + e.lineNumber + "\nMessage: " + e.message);
     127                        throw ( "Error in " + file.getAbsolutePath() + "\n" + "Line: " + e.lineNumber + "\nMessage: " + e.message );
    127128                }
    128129        }
    129130
    130131        var regexLib =
    131132        {
    132                 inlineComment :Pattern.compile( "^\\s*\\/\\/" ),
    133                 missing :Pattern.compile( "\\/\\/\\s*MISSING", Pattern.CASE_INSENSITIVE ),
    134                 blockCommentStart :Pattern.compile( "\\/\\*" ),
    135                 blockCommentEnd :Pattern.compile( "\\*\\/" ),
    136                 entry :Pattern.compile( "^(\\s*)([a-z0-9][_a-z0-9]*)(\\s*:\\s*\\').*?(\\'.*)$", Pattern.CASE_INSENSITIVE ),
    137                 arrayEntry :Pattern.compile( "^(\\s*)([a-z0-9][_a-z0-9]*)(\\s*:\\s*\\[)(.*?)(\\].*)$", Pattern.CASE_INSENSITIVE ),
    138                 arrayItemEntry :Pattern.compile( "\\s*(?:'(.*?)'(?:\\s*,\\s*)?)" ),
    139                 arrayTranslationKey :Pattern.compile( "^(.*)\\[(\\d+)\\]$" ),
    140                 objectName :Pattern.compile( "^\\s*([a-z][_a-z0-9]*)\\s*:\\s*$", Pattern.CASE_INSENSITIVE ),
    141                 objectStart :Pattern.compile( "\\{" ),
    142                 objectEnd :Pattern.compile( "\\}" ),
    143                 fileOverview :Pattern.compile( " @fileOverview" ),
    144                 translation :Pattern.compile( "#ckeditor_translation[^#]*?#" ),
    145                 ckeditorLang :Pattern.compile( "(.*CKEDITOR\\.lang\\[).*?(\\]\\s*=.*)" )
     133                inlineComment : Pattern.compile( "^\\s*\\/\\/" ),
     134                inlineCommentAtTheEndOfLine : Pattern.compile( "\\S+\\s*(\\/\\/.*)$" ),
     135                missing : Pattern.compile( "\\/\\/\\s*MISSING", Pattern.CASE_INSENSITIVE ),
     136                blockCommentStart : Pattern.compile( "\\/\\*" ),
     137                blockCommentEnd : Pattern.compile( "\\*\\/" ),
     138                entry : Pattern.compile( "^(\\s*)([a-z0-9][_a-z0-9]*)(\\s*:\\s*\\').*?(\\'.*)$", Pattern.CASE_INSENSITIVE ),
     139                arrayEntry : Pattern.compile( "^(\\s*)([a-z0-9][_a-z0-9]*)(\\s*:\\s*\\[)(.*?)(\\].*)$", Pattern.CASE_INSENSITIVE ),
     140                arrayItemEntry : Pattern.compile( "\\s*(?:'(.*?)'(?:\\s*,\\s*)?)" ),
     141                arrayTranslationKey : Pattern.compile( "^(.*)\\[(\\d+)\\]$" ),
     142                objectName : Pattern.compile( "^\\s*([a-z][_a-z0-9]*)\\s*:\\s*(:?\\/\\/.*)?$", Pattern.CASE_INSENSITIVE ),
     143                objectStart : Pattern.compile( "\\{" ),
     144                objectEnd : Pattern.compile( "\\}" ),
     145                fileOverview : Pattern.compile( " @fileOverview" ),
     146                copyright : Pattern.compile( "Copyright" ),
     147                translation : Pattern.compile( "#ckeditor_translation[^#]*?#" ),
     148                ckeditorLang : Pattern.compile( "(.*CKEDITOR\\.lang\\[).*?(\\]\\s*=.*)" )
    146149        };
    147150
    148151        /**
     
    150153         */
    151154        function analyzeLanguageFile( file )
    152155        {
    153                 fileOverviewBlock = '/**\n* @fileOverview \n*/';
     156                fileOverviewBlock = '/**' + CKLANGTOOL.EOL + '* @fileOverview ' + CKLANGTOOL.EOL + '*/';
    154157
    155158                var key = "ckeditor_translation";
    156                 var out =
    157                 {};
     159                var out = {};
    158160                var inBlockComment = false;
    159161                var blockComment = [];
    160162                var objectName, matcher, line, translationKey;
     
    162164
    163165                for ( var j = 0 ; j < lines.length ; j++ )
    164166                {
    165                         line = lines[ j ];
     167                        line = lines[j];
    166168                        if ( !inBlockComment )
    167169                        {
    168170                                matcher = regexLib.inlineComment.matcher( line );
     
    218220                                {
    219221                                        translationKey = key + "." + matcher.group( 2 );
    220222                                        translationKey = translationKey.replace( /^ckeditor_translation\./, "" );
    221                                         out[ translationKey ] = true;
     223                                        out[translationKey] = true;
    222224                                }
    223225
    224226                                /*
     
    229231                                {
    230232                                        translationKey = key + "." + matcher.group( 2 );
    231233                                        translationKey = translationKey.replace( /^ckeditor_translation\./, "" );
    232                                         out[ translationKey ] = true;
     234                                        out[translationKey] = true;
    233235                                }
    234236                        }
    235237                        else
     
    244246                                        matcher = regexLib.fileOverview.matcher( blockComment.join( "" ) );
    245247                                        if ( matcher.find() )
    246248                                        {
    247                                                 fileOverviewBlock = blockComment.join( "\n" );
     249                                                fileOverviewBlock = blockComment.join( CKLANGTOOL.EOL );
    248250                                        }
    249251                                        blockComment = [];
    250252                                }
     
    265267         *
    266268         * #ckeditor_translation.__fileOverview# (the block comment with the file
    267269         * description)
    268          */
     270        */
    269271        function createTemplate( file )
    270272        {
    271                 var key = "ckeditor_translation";
    272                 var out = [];
     273                var o = CKLANGTOOL.loadLanguageFile( file );
     274                var comments = loadComments( file );
     275                var template = '/*' + CKLANGTOOL.EOL + CKLANGTOOL.header + CKLANGTOOL.EOL + '*/' + CKLANGTOOL.EOL;
     276
     277                for ( var i = 0 ; i < comments['_'].length ; i++ )
     278                        template = template + CKLANGTOOL.EOL + comments['_'][i] + CKLANGTOOL.EOL;
     279
     280                if ( o.type == 'CKEditor' )
     281                {
     282                        template = template + "CKEDITOR.lang['#ckeditor_translation.__languageCode#'] =" + CKLANGTOOL.EOL + "{" + CKLANGTOOL.EOL
     283                        + outObject( o.translation, "ckeditor_translation", comments, '\t' ) + CKLANGTOOL.EOL + '};' + CKLANGTOOL.EOL;
     284                }
     285                else
     286                        template += outObject( o.translation, "ckeditor_translation", comments, '' );
     287
     288                /**
     289                 * Uncomment this line to see the template.
     290                 */
     291                // CKLANGTOOL.io.saveFile( new File( CKLANGTOOL.languageDir, "template.txt" ), template, false );
     292                return template;
     293        }
     294
     295        var outString = function( str )
     296        {
     297                var value = String( str ),
     298                        singleParts = value.split( "'" ),
     299                        doubleParts = value.split( '"' );
     300
     301                value = value.replace( /[\b\t\n\v\f\r\x1b\xa0\\]/g, function( match )
     302                        {
     303                                var chars =
     304                                {
     305                                        '\b' : '\\b',
     306                                        '\t' : '\\t',
     307                                        '\n' : '\\n',
     308                                        '\v' : '\\v',
     309                                        '\f' : '\\f',
     310                                        '\r' : '\\r',
     311                                        '\\' : '\\\\',
     312                                        '\x1b' : '\\x1b',
     313                                        '\xa0' : '\\xa0'
     314                                };
     315
     316                                return chars[ match ];
     317                        } );
     318
     319                if ( doubleParts.length > singleParts.length )
     320                        return "'" + value.replace( /'/g, "\\'" ) + "'" ;
     321                else if ( singleParts.length > 1 )
     322                        return '"' + value.replace( /"/g, '\\"' ) + '"' ;
     323                else
     324                        return "'" + value + "'" ;
     325        };
     326
     327        function loadComments( file )
     328        {
     329                var comments = { '_' : [], '_eol' : [] };
     330                var commentWaiting = false;
     331
     332                var tempKey, key = "ckeditor_translation";
    273333                var inBlockComment = false;
    274                 var blockComment = [];
    275                 var i, matcher, matchResult, objectName, string, line;
    276                 var arrayEntryItems, arrayEntryItemsMatcher, arrayEntryLineEnd, arrayEntryLine, arrayEntryKey;
     334                var inlineCommentAtTheEndOfLine, blockComment = [];
     335                var arrayEntryKey, i, line, matcher, objectName;
    277336                var lines = CKLANGTOOL.io.readFileIntoArray( file );
    278337
    279338                for ( var j = 0 ; j < lines.length ; j++ )
    280339                {
    281                         line = lines[ j ];
     340                        line = lines[j];
    282341
    283342                        if ( !inBlockComment )
    284343                        {
    285344                                matcher = regexLib.inlineComment.matcher( line );
    286345                                if ( matcher.find() )
    287346                                {
    288                                         out.push( line );
     347                                        if ( commentWaiting !== false )
     348                                                commentWaiting = commentWaiting + CKLANGTOOL.EOL + line.replace( '\t', '' );
     349                                        else
     350                                                commentWaiting = line.replace( '\t', '' );
    289351                                        continue;
    290352                                }
    291353
    292354                                matcher = regexLib.blockCommentStart.matcher( line );
    293355                                if ( matcher.find() )
    294356                                {
     357                                        blockComment.push( line.replace( '\t', '' ) );
    295358                                        inBlockComment = true;
    296                                         blockComment.push( line );
    297359                                        continue;
    298360                                }
    299361
     
    301363                                if ( matcher.find() )
    302364                                {
    303365                                        objectName = matcher.group( 1 );
    304                                         out.push( line );
     366
     367                                        matcher = regexLib.inlineCommentAtTheEndOfLine.matcher( line );
     368                                        if ( matcher.find() )
     369                                                comments['_eol'][key + "." + objectName] = matcher.group( 1 );
     370
    305371                                        continue;
    306372                                }
    307373
    308374                                if ( objectName )
    309375                                {
     376                                        matcher = regexLib.inlineCommentAtTheEndOfLine.matcher( line );
     377                                        if ( matcher.find() )
     378                                                inlineCommentAtTheEndOfLine = matcher.group( 1 ); 
     379                                        else
     380                                                inlineCommentAtTheEndOfLine = false;
     381
    310382                                        matcher = regexLib.objectStart.matcher( line );
    311383                                        /*
    312384                                         * We have found an opening bracket, key -> key.objectName
     
    314386                                        if ( matcher.find() )
    315387                                        {
    316388                                                key = key + "." + objectName;
    317                                                 out.push( line );
     389
     390                                                if ( commentWaiting !== false )
     391                                                {
     392                                                        comments[key] = commentWaiting;
     393                                                        commentWaiting = false;
     394                                                }
     395
     396                                                if ( inlineCommentAtTheEndOfLine !== false )
     397                                                        comments['_eol'][key + "_1"] = inlineCommentAtTheEndOfLine;
     398                                               
    318399                                                continue;
    319400                                        }
     401                                        else
     402                                        {
     403                                                tempKey = key;
    320404
     405                                                matcher = regexLib.entry.matcher( line.replaceAll( "\\\\'", "" ) );
     406                                                if ( matcher.find() )
     407                                                        tempKey = key + "." + matcher.group( 2 );
     408
     409                                                if ( inlineCommentAtTheEndOfLine !== false )
     410                                                        comments['_eol'][tempKey] = inlineCommentAtTheEndOfLine;
     411
     412                                                if ( commentWaiting !== false )
     413                                                {
     414                                                        comments[tempKey] = commentWaiting;
     415                                                        commentWaiting = false;
     416                                                }
     417                                        }
     418
    321419                                        matcher = regexLib.objectEnd.matcher( line );
    322420                                        /*
    323421                                         * We have found a closing bracket, key.objectName -> key
     
    325423                                        if ( matcher.find() )
    326424                                        {
    327425                                                key = key.slice( 0, key.lastIndexOf( "." ) );
    328                                                 out.push( line );
    329426                                                continue;
    330427                                        }
    331428                                }
    332429
    333                                 /*
    334                                  * Find CKEDITOR.lang['en']
    335                                  */
    336                                 matcher = regexLib.ckeditorLang.matcher( line );
    337                                 if ( matcher.find() )
     430                                if ( commentWaiting !== false )
    338431                                {
    339                                         out.push( matcher.group( 1 ) + "'#ckeditor_translation.__languageCode#'" + matcher.group( 2 ) );
    340                                         continue;
    341                                 }
     432                                        /*
     433                                         * Get rid of all escaped quotes, we don't need the exact content at this stage, just the key.
     434                                         * We're changing here the entry into the key.
     435                                         * So 'Upload' becomes '#ckeditor_translation.Upload#' in our temporary template. 
     436                                         */
     437                                        matcher = regexLib.entry.matcher( line.replaceAll( "\\\\'", "" ) );
     438                                        if ( matcher.find() )
     439                                        {
     440                                                comments[key + "." + matcher.group( 2 )] = commentWaiting;
     441                                                commentWaiting = false;
     442                                                continue;
     443                                        }
    342444
    343                                 /*
    344                                  * Get rid of all escaped quotes, we don't need the exact content at this stage, just the key.
    345                                  * We're changing here the entry into the key.
    346                                  * So 'Upload' becomes '#ckeditor_translation.Upload#' in our temporary template. 
    347                                  */
    348                                 matcher = regexLib.entry.matcher( line.replaceAll( "\\\\'", "" ) );
    349                                 if ( matcher.find() )
    350                                 {
    351                                         out.push( matcher.group( 1 ) + matcher.group( 2 ) + matcher.group( 3 ) + "#" + key + "." + matcher.group( 2 ) + "#"
    352                                                         + matcher.group( 4 ) );
    353                                         continue;
    354                                 }
    355 
    356                                 /*
    357                                  * Get rid of all escaped quotes, we don't need the exact content at this stage, just the key.
    358                                  * We're changing here the entry into the key.
    359                                  * So ['AM', 'PM'] becomes
    360                                  * ['#ckeditor_translation.DateAmPm[0]#', '#ckeditor_translation.DateAmPm[1]#']
    361                                  * in our temporary template. 
    362                                  */
    363                                 matcher = regexLib.arrayEntry.matcher( line.replaceAll( "\\\\'", "" ) );
    364                                 if ( matcher.find() )
    365                                 {
    366                                         i = 0;
    367 
    368                                         arrayEntryLine = matcher.group( 1 ) + matcher.group( 2 ) + matcher.group( 3 );
    369                                         arrayEntryKey = matcher.group( 2 );
    370                                         arrayEntryLineEnd = matcher.group( 5 );
    371                                         arrayEntryItems = matcher.group( 4 );
    372 
    373                                         arrayEntryItemsMatcher = regexLib.arrayItemEntry.matcher( arrayEntryItems );
    374                                         while ( arrayEntryItemsMatcher.find() )
     445                                        /*
     446                                         * Get rid of all escaped quotes, we don't need the exact content at this stage, just the key.
     447                                         * We're changing here the entry into the key.
     448                                         * So ['AM', 'PM'] becomes
     449                                         * ['#ckeditor_translation.DateAmPm[0]#', '#ckeditor_translation.DateAmPm[1]#']
     450                                         * in our temporary template. 
     451                                         */
     452                                        matcher = regexLib.arrayEntry.matcher( line.replaceAll( "\\\\'", "" ) );
     453                                        if ( matcher.find() )
    375454                                        {
    376                                                 matchResult = arrayEntryItemsMatcher.toMatchResult();
    377                                                 if ( i > 0 )
    378                                                 {
    379                                                         arrayEntryLine += ", ";
    380                                                 }
    381                                                 arrayEntryLine += "'#" + key + "." + arrayEntryKey + "[" + i + "]" + "#'";
    382                                                 i++;
     455                                                arrayEntryKey = matcher.group( 2 );
     456                                                comments[key + "." + arrayEntryKey] = commentWaiting;
     457                                                commentWaiting = false;
     458                                                continue;
    383459                                        }
    384                                         arrayEntryLine += arrayEntryLineEnd;
    385                                         out.push( arrayEntryLine );
    386                                         continue;
    387460                                }
    388 
    389                                 out.push( line );
    390461                        }
    391462                        else
    392463                        {
    393                                 blockComment.push( line );
     464                                blockComment.push( line.replace( '\t', '' ) );
    394465
    395466                                matcher = regexLib.blockCommentEnd.matcher( line );
    396467                                if ( matcher.find() )
    397468                                {
    398469                                        inBlockComment = false;
     470                                        if ( commentWaiting !== false )
     471                                                comments['_'].push( commentWaiting );
    399472
    400                                         matcher = regexLib.fileOverview.matcher( blockComment.join( "" ) );
    401                                         /**
    402                                          * Add a placeholder for the fileOverview section.
    403                                          */
    404                                         if ( matcher.find() )
     473                                        // Ignore Copyright comment.
     474                                        matcher = regexLib.copyright.matcher( blockComment.join( "" ) );
     475                                        if ( !matcher.find() )
    405476                                        {
    406                                                 out.push( "#ckeditor_translation.__fileOverview#" );
     477                                                matcher = regexLib.fileOverview.matcher( blockComment.join( "" ) );
     478                                                if ( matcher.find() )
     479                                                        comments['_'].push( "#ckeditor_translation.__fileOverview#" );
     480                                                else
     481                                                        commentWaiting = blockComment.join( CKLANGTOOL.EOL );
    407482                                        }
    408                                         else
    409                                         {
    410                                                 out.push( blockComment.join( "\n" ) );
    411                                         }
     483
    412484                                        blockComment = [];
    413485                                }
    414486                        }
    415487                }
    416488
    417                 /**
    418                  * Uncomment this line to see the template.
    419                  */
    420                 // CKLANGTOOL.io.saveFile( new File( CKLANGTOOL.languageDir, "template.txt" ), out.join( "\r\n" ), false );
    421                 return out.join( "\n" ).replace(/\s*$/, "\n");
     489                return comments;
    422490        }
    423491
     492        function outObject( o, key, comments, suffix )
     493        {
     494                var i, objects = [], strings = [], out = [], line;
     495
     496                for( i in o )
     497                {
     498                        if ( typeof o[i] == 'string' )
     499                                strings.push( i );
     500                        else
     501                                objects.push( i );
     502                }
     503
     504                strings.sort();
     505                objects.sort();
     506               
     507                for ( i = 0 ; i < strings.length ; i++ )
     508                {
     509                        if ( comments[key + "." + strings[i]] )
     510                        {
     511                                out.push( suffix + String( comments[key + "." + strings[i]] ).replace( /(?:\r\n|\r|\n)/g, CKLANGTOOL.EOL + suffix ) );
     512                        }
     513
     514                        if ( !/^(?:[a-zA-Z$_][\w$_]*)$/.test( strings[i] ) )
     515                                line = suffix + outString( strings[i] ) + " : '#" + key + "." + strings[i] + "#'";
     516                        else
     517                                line = suffix + strings[i] + " : '#" + key + "." + strings[i] + "#'";
     518
     519                        if ( objects.length || i != strings.length - 1 )
     520                                line += ',';
     521
     522                        if ( comments['_eol'][key + "." + strings[i]] )
     523                                line += " " + comments['_eol'][key + "." + strings[i]];
     524
     525                        out.push( line );
     526                }
     527
     528                if (strings.length && objects.length)
     529                        out.push( "" );
     530
     531                for ( i = 0 ; i < objects.length ; i++ )
     532                {
     533                        if ( i > 0 )
     534                                out.push( "" );
     535
     536                        if ( comments[key + "." + objects[i]] )
     537                        {
     538                                out.push( suffix + String( comments[key + "." + objects[i]] ).replace( /(?:\r\n|\r|\n)/g, CKLANGTOOL.EOL + suffix ) );
     539                        }
     540
     541                        line = suffix + objects[i] + ' :';
     542                       
     543                        if ( comments['_eol'][key + "." + objects[i]] )
     544                                line += " " + comments['_eol'][key + "." + objects[i]];
     545
     546                        out.push( line );
     547                        out.push( suffix + '{' );
     548
     549                        out.push( outObject( o[objects[i]], key + "." + objects[i], comments, suffix + '\t' ) );
     550
     551                        if ( i == objects.length -1 )
     552                                out.push( suffix + '}' );
     553                        else
     554                                out.push( suffix + '},' );
     555                }
     556               
     557                return out.join( CKLANGTOOL.EOL );
     558        }
     559
    424560        /**
    425561         * Return translation[translationKey].
    426562         *
     
    444580                if ( translationKey == "__fileOverview" )
    445581                        return fileOverviewBlock;
    446582
    447                 while ( (dotPos = translationKey.indexOf( "." )) != -1 )
     583                while ( ( dotPos = translationKey.indexOf( "." ) ) != -1 )
    448584                {
    449                         result = result[ translationKey.substring( 0, dotPos ) ];
    450                         if ( typeof (result) == "undefined" )
     585                        result = result[translationKey.substring( 0, dotPos )];
     586                        if ( typeof ( result ) == "undefined" )
    451587                        {
    452588                                return false;
    453589                        }
     
    460596                var matcher = regexLib.arrayTranslationKey.matcher( translationKey );
    461597                if ( matcher.find() )
    462598                {
    463                         if ( typeof (result[ matcher.group( 1 ) ]) != "object" )
     599                        if ( typeof ( result[matcher.group( 1 )] ) != "object" )
    464600                        {
    465601                                return false;
    466602                        }
    467                         result = result[ matcher.group( 1 ) ][ matcher.group( 2 ) ];
     603                        result = result[matcher.group( 1 )][matcher.group( 2 )];
    468604                }
    469605                else
    470606                {
    471                         result = result[ translationKey ];
     607                        result = result[translationKey];
    472608                }
    473609
    474                 if ( typeof (result) == "undefined" )
     610                if ( typeof ( result ) == "undefined" )
    475611                {
    476612                        return false;
    477613                }
     
    484620         */
    485621        function escapeString( string )
    486622        {
    487                 return string.replace( /\\/g, "\\\\" ).replace( /\r/g, "\\r" ).replace( /\n/g, "\\n" ).replace( /'/g, "\\'" ).replace( /\u200b/g,
    488                                 "\\u200b" );
     623                return string.replace( /\\/g, "\\\\" ).replace( /\r/g, "\\r" ).replace( /\n/g, "\\n" ).replace( /'/g, "\\'" ).replace(
     624                                /\u200b/g, "\\u200b" );
    489625        }
    490626
    491627        function processFile( file )
     
    512648                        /*
    513649                         * common.textField[1] -> common.textField
    514650                         */
    515                         if ( replacement == false || missingKeys[ translationKey.replace( /\[\d+\]$/, "" ) ] )
     651                        if ( replacement == false || missingKeys[translationKey.replace( /\[\d+\]$/, "" )] )
    516652                        {
    517653                                /**
    518654                                 * FoldersTitle : '#ckeditor_translation.FoldersTitle#', ->
    519655                                 * FoldersTitle : '[MISSING_TRANSLATION]Folders',
    520656                                 */
    521657                                replacement = "[MISSING_TRANSLATION]" + getTranslation( CKLANGTOOL.englishTranslation, translationKey );
    522                                 string = (string.substring( 0, matchResult.start() ) + replacement + string.substring( matchResult.end() ));
     658                                string = ( string.substring( 0, matchResult.start() ) + replacement + string.substring( matchResult.end() ) );
    523659
    524660                                if ( translationKey.substring( 0, 2 ) != "__" )
    525661                                        missing++;
    526662                        }
    527663                        else
    528664                        {
    529                                 string = (string.substring( 0, matchResult.start() ) + replacement + string.substring( matchResult.end() ));
     665                                string = ( string.substring( 0, matchResult.start() ) + replacement + string.substring( matchResult.end() ) );
    530666
    531667                                if ( translationKey.substring( 0, 2 ) != "__" )
    532668                                        found++;
     
    539675                 * Loop through all lines, remove [MISSING_TRANSLATION] and add
    540676                 * //MISSING comment at the end of line (if necessary).
    541677                 */
    542                 var line, lines = string.split( "\n" );
     678                var line, lines = string.split( CKLANGTOOL.EOL );
    543679                for ( var i = 0 ; i < lines.length ; i++ )
    544680                {
    545                         line = lines[ i ];
     681                        line = lines[i];
    546682                        if ( line.indexOf( "[MISSING_TRANSLATION]" ) != -1 )
    547683                        {
    548684                                if ( line.indexOf( "//" ) == -1 )
    549685                                {
    550                                         lines[ i ] = line.replace( /\[MISSING_TRANSLATION\]/g, '' ) + " // MISSING";
     686                                        lines[i] = line.replace( /\[MISSING_TRANSLATION\]/g, '' ) + " // MISSING";
    551687                                }
    552688                                else
    553689                                {
    554                                         lines[ i ] = line.replace( "//", "// MISSING //" ).replace( /\[MISSING_TRANSLATION\]/g, '' );
     690                                        lines[i] = line.replace( "//", "// MISSING //" ).replace( /\[MISSING_TRANSLATION\]/g, '' );
    555691                                }
    556692                        }
    557693                }
    558694
    559                 CKLANGTOOL.io.saveFile( file, lines.join( "\r\n" ), false );
     695                CKLANGTOOL.io.saveFile( file, lines.join( CKLANGTOOL.EOL ), true );
    560696
    561697                var result =
    562698                {
    563                         found :found,
    564                         missing :missing
     699                        found : found,
     700                        missing : missing
    565701                };
    566702
    567703                return result;
     
    577713                run : function()
    578714                {
    579715                        CKLANGTOOL.template = createTemplate( CKLANGTOOL.templateFile );
    580                         var result = CKLANGTOOL.loadLanguageFile( CKLANGTOOL.templateFile ); 
    581                         CKLANGTOOL.englishTranslation = result.translation; 
     716                        var result = CKLANGTOOL.loadLanguageFile( CKLANGTOOL.templateFile );
     717                        CKLANGTOOL.englishTranslation = result.translation;
    582718
    583719                        var children = CKLANGTOOL.languageDir.list();
    584720                        var errors, file, status = [];
     
    586722
    587723                        for ( var i = 0 ; i < children.length ; i++ )
    588724                        {
    589                                 if ( children[ i ] == 'en.js' )
    590                                         continue;
    591 
    592725                                /**
    593726                                 * Skip files beginning with underscore character.
    594727                                 */
    595                                 if ( children[ i ].charAt(0) == 95 )
     728                                if ( children[i].charAt( 0 ) == 95 )
    596729                                        continue;
    597                                
    598                                 if ( CKLANGTOOL.io.getExtension( children[ i ] ) != "js" )
     730
     731                                if ( CKLANGTOOL.io.getExtension( children[i] ) != "js" )
    599732                                        continue;
    600733
    601                                 file = new File( CKLANGTOOL.languageDir, children[ i ] );
     734                                file = new File( CKLANGTOOL.languageDir, children[i] );
    602735                                if ( file.isFile() )
    603736                                {
    604737                                        print( "Processing " + file.getAbsolutePath() );
    605738                                        result = processFile( file );
    606739                                        checkFile( file );
    607740
    608                                         status.push( padRight( children[ i ], 12 ) + "Found: " + result.found + " Missing: " + result.missing );
     741                                        status.push( padRight( children[i], 12 ) + "Found: " + result.found + " Missing: " + result.missing );
    609742                                        foundFiles = true;
    610743                                }
    611744                        }
     
    615748                                print( "WARNING: language files not found." );
    616749                        }
    617750
    618                         var header = "Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.\r\nFor licensing, see LICENSE.html or http://ckeditor.com/license\r\n\r\n";
    619 
    620                         CKLANGTOOL.io.saveFile( new File( CKLANGTOOL.languageDir, "_translationstatus.txt" ), header + status.join( "\r\n" ) + "\r\n", false );
     751                        CKLANGTOOL.io.saveFile( new File( CKLANGTOOL.languageDir, "_translationstatus.txt" ), CKLANGTOOL.header + CKLANGTOOL.EOL + CKLANGTOOL.EOL + status.join( CKLANGTOOL.EOL ),
     752                                        true );
    621753                        print( "Process completed." );
    622754                }
    623755        };
  • test/_assets/translator/_translationstatus.txt.correct.txt

     
    1 Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
     1Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
    22For licensing, see LICENSE.html or http://ckeditor.com/license
    33
    4 de.js      Found: 17 Missing: 4
    5 pl.js      Found: 18 Missing: 3
     4ar.js      Found: 24 Missing: 1
     5de.js      Found: 20 Missing: 5
     6en.js      Found: 25 Missing: 0
     7pl.js      Found: 22 Missing: 3
     8 No newline at end of file
  • test/_assets/translator/ar.js

     
     1/*
     2Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
     3For licensing, see LICENSE.html or http://ckeditor.com/license
     4*/
     5
     6/**
     7 * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
     8 * Arabic language.
     9 */
     10
     11/**#@+
     12   @type String
     13   @example
     14*/
     15
     16/**
     17 * Constains the dictionary of language entries.
     18 * @namespace
     19 */
     20CKEDITOR.lang['ar'] =
     21{
     22        /**
     23         * The language reading direction. Possible values are "rtl" for
     24         * Right-To-Left languages (like Arabic) and "ltr" for Left-To-Right
     25         * languages (like English).
     26         * @default 'ltr'
     27         */
     28        dir : 'rtl',
     29
     30        // Toolbar buttons without dialogs.
     31        source                  : 'المصدر',
     32        newPage                 : 'صفحة جديدة',
     33        save                    : 'حفظ',
     34        preview                 : 'معاينة الصفحة',
     35
     36        // Common messages and labels.
     37        common :
     38        {
     39                browseServer            : 'تصفح',
     40                url                     : 'الرابط',
     41                protocol                : 'البروتوكول',
     42                confirmCancel   : 'بعض الخيارات قد تغيرت. هل أنت متأكد من إغلاق مربع النص؟',
     43        },
     44
     45        // Special char dialog.
     46        specialChar             :
     47        {
     48                toolbar         : 'إدراج  خاص.ِ',
     49                title           : 'اختر الخواص'
     50        },
     51
     52        // Link dialog.
     53        link :
     54        {
     55                toolbar         : 'رابط',
     56                noAnchors               : '(لا توجد علامات مرجعية في هذا المستند)',
     57                noUrl                   : 'من فضلك أدخل عنوان الموقع الذي يشير إليه الرابط',
     58                noEmail                 : 'من فضلك أدخل عنوان البريد الإلكتروني'
     59        },
     60
     61        // Table Dialog
     62        table :
     63        {
     64                toolbar         : 'جدول',
     65
     66                cell :
     67                {
     68                        menu                    : 'خلية',
     69                        insertBefore    : 'إدراج خلية قبل'
     70                },
     71
     72                row :
     73                {
     74                        menu                    : 'صف'
     75                }
     76        },
     77
     78        // Button Dialog.
     79        button :
     80        {
     81                typeRst         : 'إعادة تعيين'
     82        },
     83
     84        colors :
     85        {
     86                '000' : 'أسود',
     87                '800000' : 'كستنائي',
     88                'E6E6FA' : 'أرجواني',
     89                'FFF' : 'أبيض'
     90        }
     91};
  • test/_assets/translator/ar.js.correct.txt

     
     1/*
     2Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
     3For licensing, see LICENSE.html or http://ckeditor.com/license
     4*/
     5
     6/**
     7 * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
     8 * Arabic language.
     9 */
     10
     11/**#@+
     12   @type String
     13   @example
     14*/
     15
     16/**
     17 * Constains the dictionary of language entries.
     18 * @namespace
     19 */
     20CKEDITOR.lang['ar'] =
     21{
     22        /**
     23         * The language reading direction. Possible values are "rtl" for
     24         * Right-To-Left languages (like Arabic) and "ltr" for Left-To-Right
     25         * languages (like English).
     26         * @default 'ltr'
     27         */
     28        dir : 'rtl',
     29        /*
     30         * Screenreader titles. Please note that screenreaders are not always capable
     31         * of reading non-English words. So be careful while translating it.
     32         */
     33        editorTitle : 'Rich text editor, %1', // MISSING
     34        newPage : 'صفحة جديدة',
     35        preview : 'معاينة الصفحة',
     36        save : 'حفظ',
     37        // Toolbar buttons without dialogs.
     38        source : 'المصدر',
     39
     40        // Button Dialog.
     41        button :
     42        {
     43                typeRst : 'إعادة تعيين'
     44        },
     45
     46        colors :
     47        {
     48                '000' : 'أسود',
     49                '800000' : 'كستنائي',
     50                E6E6FA : 'أرجواني',
     51                FFF : 'أبيض'
     52        },
     53
     54        // Common messages and labels.
     55        // Inline comment
     56        // having more than one line.
     57        common :
     58        {
     59                browseServer : 'تصفح',
     60                confirmCancel : 'بعض الخيارات قد تغيرت. هل أنت متأكد من إغلاق مربع النص؟',
     61                protocol : 'البروتوكول',
     62                url : 'الرابط'
     63        },
     64
     65        // Link dialog.
     66        link :
     67        {
     68                noAnchors : '(لا توجد علامات مرجعية في هذا المستند)',
     69                noEmail : 'من فضلك أدخل عنوان البريد الإلكتروني',
     70                noUrl : 'من فضلك أدخل عنوان الموقع الذي يشير إليه الرابط',
     71                toolbar : 'رابط' // IE6 BUG: A title called "Link" in an <A> tag would invalidate its padding!!
     72        },
     73
     74        // Special char dialog.
     75        specialChar : // Inline comment for special char dialog.
     76        {
     77                title : 'اختر الخواص',
     78                toolbar : 'إدراج  خاص.ِ'
     79        },
     80
     81        // Table Dialog
     82        table :
     83        {
     84                toolbar : 'جدول',
     85
     86                cell :
     87                {
     88                        insertBefore : 'إدراج خلية قبل',
     89                        menu : 'خلية'
     90                },
     91
     92                row :
     93                {
     94                        menu : 'صف'
     95                }
     96        }
     97};
  • test/_assets/translator/de.js

     
    5151        // Link dialog.
    5252        link :
    5353        {
    54                 toolbar         : 'Link einfügen/editieren',            // IE6 BUG: A title called "Link" in an <A> tag would invalidate its padding!!
     54                toolbar         : 'Link\u200b',         // MISSING // IE6 BUG: A title called "Link" in an <A> tag would invalidate its padding!!
    5555                noAnchors               : '(keine Anker im Dokument vorhanden)',
    5656                noUrl                   : 'Bitte geben Sie die Link-URL an',
    5757                noEmail                 : 'Bitte geben Sie e-Mail Adresse an'
     
    7474                },
    7575        },
    7676
     77        colors :
     78        {
     79                '000' : 'Schwarz',
     80                '800000' : 'Kastanienbraun',
     81                'E6E6FA' : 'Lavendel',
     82                'FFF' : 'Weiß'
     83        },
     84
    7785        // Button Dialog.
    7886        button :
    7987        {
    8088                typeRst         : 'Zurücksetzen'
    81         },
     89        }
    8290};
    8391
    8492
  • test/_assets/translator/de.js.correct.txt

     
    2626         * @default 'ltr'
    2727         */
    2828        dir : 'ltr',
    29 
    3029        /*
    3130         * Screenreader titles. Please note that screenreaders are not always capable
    3231         * of reading non-English words. So be careful while translating it.
    3332         */
    34         editorTitle             : 'Rich text editor, %1', // MISSING
    35 
     33        editorTitle : 'Rich text editor, %1', // MISSING
     34        newPage : 'Neue Seite',
     35        preview : 'Vorschau',
     36        save : 'Speichern',
    3637        // Toolbar buttons without dialogs.
    37         source                  : 'Quellcode',
    38         newPage                 : 'Neue Seite',
    39         save                    : 'Speichern',
    40         preview                 : 'Vorschau',
     38        source : 'Quellcode',
    4139
    42         // Common messages and labels.
    43         common :
     40        // Button Dialog.
     41        button :
    4442        {
    45                 browseServer    : 'Server durchsuchen',
    46                 url                             : 'Bildauswahl',
    47                 protocol                : 'Protokoll',
    48                 confirmCancel   : 'Some of the options have been changed. Are you sure to close the dialog?' // MISSING
     43                typeRst : 'Zurücksetzen'
    4944        },
    5045
    51         // Special char dialog.
    52         specialChar             :
     46        colors :
    5347        {
    54                 toolbar         : 'Insert Special Character', // MISSING
    55                 title           : 'Select Special Character' // MISSING
     48                '000' : 'Schwarz',
     49                '800000' : 'Kastanienbraun',
     50                E6E6FA : 'Lavendel',
     51                FFF : 'Weiß'
    5652        },
    5753
     54        // Common messages and labels.
     55        // Inline comment
     56        // having more than one line.
     57        common :
     58        {
     59                browseServer : 'Server durchsuchen',
     60                confirmCancel : 'Some of the options have been changed. Are you sure to close the dialog?', // MISSING
     61                protocol : 'Protokoll',
     62                url : 'Bildauswahl'
     63        },
     64
    5865        // Link dialog.
    5966        link :
    6067        {
    61                 toolbar         : 'Link einfügen/editieren',            // IE6 BUG: A title called "Link" in an <A> tag would invalidate its padding!!
    62                 noAnchors               : '(keine Anker im Dokument vorhanden)',
    63                 noUrl                   : 'Bitte geben Sie die Link-URL an',
    64                 noEmail                 : 'Bitte geben Sie e-Mail Adresse an'
     68                noAnchors : '(keine Anker im Dokument vorhanden)',
     69                noEmail : 'Bitte geben Sie e-Mail Adresse an',
     70                noUrl : 'Bitte geben Sie die Link-URL an',
     71                toolbar : 'Link\u200b' // MISSING // IE6 BUG: A title called "Link" in an <A> tag would invalidate its padding!!
    6572        },
    6673
     74        // Special char dialog.
     75        specialChar : // Inline comment for special char dialog.
     76        {
     77                title : 'Select Special Character', // MISSING
     78                toolbar : 'Insert Special Character' // MISSING
     79        },
     80
    6781        // Table Dialog
    6882        table :
    6983        {
    70                 toolbar         : 'Tabelle',
     84                toolbar : 'Tabelle',
    7185
    7286                cell :
    7387                {
    74                         menu                    : 'Zelle',
    75                         insertBefore    : 'Zelle davor einfügen',
     88                        insertBefore : 'Zelle davor einfügen',
     89                        menu : 'Zelle'
    7690                },
    7791
    7892                row :
    7993                {
    80                         menu                    : 'Zeile',
    81                 },
    82         },
    83 
    84         // Button Dialog.
    85         button :
    86         {
    87                 typeRst         : 'Zurücksetzen'
    88         },
     94                        menu : 'Zeile'
     95                }
     96        }
    8997};
  • test/_assets/translator/en.js

     
    4040        preview                 : 'Preview',
    4141
    4242        // Common messages and labels.
     43        // Inline comment
     44        // having more than one line.
    4345        common :
    4446        {
    4547                browseServer    : 'Browser Server',
     
    4951        },
    5052
    5153        // Special char dialog.
    52         specialChar             :
     54        specialChar             :       // Inline comment for special char dialog.
    5355        {
    5456                toolbar         : 'Insert Special Character',
    5557                title           : 'Select Special Character'
     
    8183                },
    8284        },
    8385
     86        colors :
     87        {
     88                '000' : 'Black',
     89                '800000' : 'Maroon',
     90                'E6E6FA' : 'Lavender',
     91                'FFF' : 'White'
     92        },
     93
    8494        // Button Dialog.
    8595        button :
    8696        {
  • test/_assets/translator/en.js.correct.txt

     
     1/*
     2Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
     3For licensing, see LICENSE.html or http://ckeditor.com/license
     4*/
     5
     6/**
     7 * @fileOverview Defines the {@link CKEDITOR.lang} object, for the English
     8 *              language. This is the base file for all translations.
     9 */
     10
     11/**#@+
     12   @type String
     13   @example
     14*/
     15
     16/**
     17 * Constains the dictionary of language entries.
     18 * @namespace
     19 */
     20CKEDITOR.lang['en'] =
     21{
     22        /**
     23         * The language reading direction. Possible values are "rtl" for
     24         * Right-To-Left languages (like Arabic) and "ltr" for Left-To-Right
     25         * languages (like English).
     26         * @default 'ltr'
     27         */
     28        dir : 'ltr',
     29        /*
     30         * Screenreader titles. Please note that screenreaders are not always capable
     31         * of reading non-English words. So be careful while translating it.
     32         */
     33        editorTitle : 'Rich text editor, %1',
     34        newPage : 'New Page',
     35        preview : 'Preview',
     36        save : 'Save',
     37        // Toolbar buttons without dialogs.
     38        source : 'Source',
     39
     40        // Button Dialog.
     41        button :
     42        {
     43                typeRst : 'Reset'
     44        },
     45
     46        colors :
     47        {
     48                '000' : 'Black',
     49                '800000' : 'Maroon',
     50                E6E6FA : 'Lavender',
     51                FFF : 'White'
     52        },
     53
     54        // Common messages and labels.
     55        // Inline comment
     56        // having more than one line.
     57        common :
     58        {
     59                browseServer : 'Browser Server',
     60                confirmCancel : 'Some of the options have been changed. Are you sure to close the dialog?',
     61                protocol : 'Protocol',
     62                url : 'URL'
     63        },
     64
     65        // Link dialog.
     66        link :
     67        {
     68                noAnchors : '(No anchors available in the document)',
     69                noEmail : 'Please type the e-mail address',
     70                noUrl : 'Please type the link URL',
     71                toolbar : 'Link\u200b' // IE6 BUG: A title called "Link" in an <A> tag would invalidate its padding!!
     72        },
     73
     74        // Special char dialog.
     75        specialChar : // Inline comment for special char dialog.
     76        {
     77                title : 'Select Special Character',
     78                toolbar : 'Insert Special Character'
     79        },
     80
     81        // Table Dialog
     82        table :
     83        {
     84                toolbar : 'Table',
     85
     86                cell :
     87                {
     88                        insertBefore : 'Insert Cell Before',
     89                        menu : 'Cell'
     90                },
     91
     92                row :
     93                {
     94                        menu : 'Row'
     95                }
     96        }
     97};
  • test/_assets/translator/pl.js

     
    4343        },
    4444
    4545        // Special char dialog.
    46         specialChar             :
     46        'specialChar'           :
    4747        {
    4848                toolbar         : 'Wstaw znak specjalny',
    49                 title           : 'Wybierz znak specjalny'
     49                'title'         : 'Wybierz znak specjalny'
    5050        },
    5151
    5252        // Link dialog.
    5353        link :
    5454        {
    55                 toolbar         : 'Wstaw/edytuj hiperłącze',            // IE6 BUG: A title called "Link" in an <A> tag would invalidate its padding!!
     55                'toolbar'               : 'Wstaw/edytuj hiperłącze',            // IE6 BUG: A title called "Link" in an <A> tag would invalidate its padding!!
    5656                noAnchors               : '(W dokumencie nie zdefiniowano żadnych etykiet)',
    5757                noUrl                   : 'Podaj adres URL',
    5858                noEmail                 : 'Podaj adres e-mail'
     
    7575                },
    7676        },
    7777
     78        colors :
     79        {
     80                '000' : 'Czarny',
     81                '800000' : 'Rdzawy',
     82                'E6E6FA' : 'Lawendowy',
     83                'FFF' : 'Biały'
     84        },
     85
    7886        // Button Dialog.
    7987        button :
    8088        {
  • test/_assets/translator/pl.js.correct.txt

     
    2626         * @default 'ltr'
    2727         */
    2828        dir : 'ltr',
    29 
    3029        /*
    3130         * Screenreader titles. Please note that screenreaders are not always capable
    3231         * of reading non-English words. So be careful while translating it.
    3332         */
    34         editorTitle             : 'Rich text editor, %1', // MISSING
    35 
     33        editorTitle : 'Rich text editor, %1', // MISSING
     34        newPage : 'Nowa strona',
     35        preview : 'Podgląd',
     36        save : 'Zapisz',
    3637        // Toolbar buttons without dialogs.
    37         source                  : 'Źródło dokumentu',
    38         newPage                 : 'Nowa strona',
    39         save                    : 'Zapisz',
    40         preview                 : 'Podgląd',
     38        source : 'Źródło dokumentu',
    4139
    42         // Common messages and labels.
    43         common :
     40        // Button Dialog.
     41        button :
    4442        {
    45                 browseServer    : 'Przeglądaj',
    46                 url                             : 'Adres URL',
    47                 protocol                : 'Protokół',
    48                 confirmCancel   : 'Some of the options have been changed. Are you sure to close the dialog?' // MISSING
     43                typeRst : 'Wyzeruj'
    4944        },
    5045
    51         // Special char dialog.
    52         specialChar             :
     46        colors :
    5347        {
    54                 toolbar         : 'Wstaw znak specjalny',
    55                 title           : 'Wybierz znak specjalny'
     48                '000' : 'Czarny',
     49                '800000' : 'Rdzawy',
     50                E6E6FA : 'Lawendowy',
     51                FFF : 'Biały'
    5652        },
    5753
     54        // Common messages and labels.
     55        // Inline comment
     56        // having more than one line.
     57        common :
     58        {
     59                browseServer : 'Przeglądaj',
     60                confirmCancel : 'Some of the options have been changed. Are you sure to close the dialog?', // MISSING
     61                protocol : 'Protokół',
     62                url : 'Adres URL'
     63        },
     64
    5865        // Link dialog.
    5966        link :
    6067        {
    61                 toolbar         : 'Wstaw/edytuj hiperłącze',            // IE6 BUG: A title called "Link" in an <A> tag would invalidate its padding!!
    62                 noAnchors               : '(W dokumencie nie zdefiniowano żadnych etykiet)',
    63                 noUrl                   : 'Podaj adres URL',
    64                 noEmail                 : 'Podaj adres e-mail'
     68                noAnchors : '(W dokumencie nie zdefiniowano żadnych etykiet)',
     69                noEmail : 'Podaj adres e-mail',
     70                noUrl : 'Podaj adres URL',
     71                toolbar : 'Wstaw/edytuj hiperłącze' // IE6 BUG: A title called "Link" in an <A> tag would invalidate its padding!!
    6572        },
    6673
     74        // Special char dialog.
     75        specialChar : // Inline comment for special char dialog.
     76        {
     77                title : 'Wybierz znak specjalny',
     78                toolbar : 'Wstaw znak specjalny'
     79        },
     80
    6781        // Table Dialog
    6882        table :
    6983        {
    70                 toolbar         : 'Tabela',
     84                toolbar : 'Tabela',
    7185
    7286                cell :
    7387                {
    74                         menu                    : 'Komórka',
    75                         insertBefore    : 'Wstaw komórkę z lewej',
     88                        insertBefore : 'Wstaw komórkę z lewej',
     89                        menu : 'Komórka'
    7690                },
    7791
    7892                row :
    7993                {
    80                         menu                    : 'Row', // MISSING
    81                 },
    82         },
    83 
    84         // Button Dialog.
    85         button :
    86         {
    87                 typeRst         : 'Wyzeruj'
    88         },
     94                        menu : 'Row' // MISSING
     95                }
     96        }
    8997};
© 2003 – 2021 CKSource – Frederico Knabben. All rights reserved. | Terms of use | Privacy policy