Home | History | Annotate | Download | only in String
      1 /* The contents of this file are subject to the Netscape Public
      2  * License Version 1.1 (the "License"); you may not use this file
      3  * except in compliance with the License. You may obtain a copy of
      4  * the License at http://www.mozilla.org/NPL/
      5  *
      6  * Software distributed under the License is distributed on an "AS
      7  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
      8  * implied. See the License for the specific language governing
      9  * rights and limitations under the License.
     10  *
     11  * The Original Code is Mozilla Communicator client code, released March
     12  * 31, 1998.
     13  *
     14  * The Initial Developer of the Original Code is Netscape Communications
     15  * Corporation. Portions created by Netscape are
     16  * Copyright (C) 1998 Netscape Communications Corporation. All
     17  * Rights Reserved.
     18  *
     19  * Contributor(s):
     20  *
     21  */
     22 /**
     23     File Name:          15.5.4.11-2.js
     24     ECMA Section:       15.5.4.11 String.prototype.toLowerCase()
     25     Description:
     26 
     27     Returns a string equal in length to the length of the result of converting
     28     this object to a string. The result is a string value, not a String object.
     29 
     30     Every character of the result is equal to the corresponding character of the
     31     string, unless that character has a Unicode 2.0 uppercase equivalent, in which
     32     case the uppercase equivalent is used instead. (The canonical Unicode 2.0 case
     33     mapping shall be used, which does not depend on implementation or locale.)
     34 
     35     Note that the toLowerCase function is intentionally generic; it does not require
     36     that its this value be a String object. Therefore it can be transferred to other
     37     kinds of objects for use as a method.
     38 
     39     Author:             christine (at) netscape.com
     40     Date:               12 november 1997
     41 */
     42 
     43     var SECTION = "15.5.4.11-2";
     44     var VERSION = "ECMA_1";
     45     startTest();
     46     var TITLE   = "String.prototype.toLowerCase()";
     47 
     48     writeHeaderToLog( SECTION + " "+ TITLE);
     49 
     50     var testcases = getTestCases();
     51     test();
     52 
     53 function getTestCases() {
     54     var array = new Array();
     55     var item = 0;
     56 
     57     // Hiragana (no upper / lower case)
     58     // Range: U+3040 to U+309F
     59 
     60     for ( var i = 0x3040; i <= 0x309F; i++ ) {
     61         var U = new Unicode( i );
     62 /*
     63         array[item++] = new TestCase(   SECTION,
     64                                         "var s = new String( String.fromCharCode("+i+") ); s.toLowerCase()",
     65                                         String.fromCharCode(U.lower),
     66                                         eval("var s = new String( String.fromCharCode("+i+") ); s.toLowerCase()") );
     67 */
     68         array[item++] = new TestCase(   SECTION,
     69                                         "var s = new String( String.fromCharCode("+i+") ); s.toLowerCase().charCodeAt(0)",
     70                                         U.lower,
     71                                         eval("var s = new String( String.fromCharCode(i) ); s.toLowerCase().charCodeAt(0)") );
     72     }
     73 
     74     return array;
     75 }
     76 function test() {
     77     for ( tc=0; tc < testcases.length; tc++ ) {
     78         testcases[tc].passed = writeTestCaseResult(
     79                             testcases[tc].expect,
     80                             testcases[tc].actual,
     81                             testcases[tc].description +" = "+
     82                             testcases[tc].actual );
     83 
     84         testcases[tc].reason += ( testcases[tc].passed ) ? "" : "wrong value ";
     85     }
     86     stopTest();
     87     return ( testcases );
     88 }
     89 function MyObject( value ) {
     90     this.value = value;
     91     this.substring = String.prototype.substring;
     92     this.toString = new Function ( "return this.value+''" );
     93 }
     94 function Unicode( c ) {
     95     this.upper = c;
     96     this.lower = c;
     97 
     98     // upper case Basic Latin
     99 
    100     if ( c >= 0x0041 && c <= 0x005A) {
    101         this.upper = c;
    102         this.lower = c + 32;
    103         return this;
    104     }
    105 
    106     // lower case Basic Latin
    107     if ( c >= 0x0061 && c <= 0x007a ) {
    108         this.upper = c - 32;
    109         this.lower = c;
    110         return this;
    111     }
    112 
    113     // upper case Latin-1 Supplement
    114     if ( (c >= 0x00C0 && c <= 0x00D6) || (c >= 0x00D8 && c<=0x00DE) ) {
    115         this.upper = c;
    116         this.lower = c + 32;
    117         return this;
    118     }
    119 
    120     // lower case Latin-1 Supplement
    121     if ( (c >= 0x00E0 && c <= 0x00F6) || (c >= 0x00F8 && c <= 0x00FE) ) {
    122         this.upper = c - 32;
    123         this.lower = c;
    124         return this;
    125     }
    126     if ( c == 0x00FF ) {
    127         this.upper = 0x0178;
    128         this.lower = c;
    129         return this;
    130     }
    131     // Latin Extended A
    132     if ( (c >= 0x0100 && c < 0x0138) || (c > 0x0149 && c < 0x0178) ) {
    133         // special case for capital I
    134         if ( c == 0x0130 ) {
    135             this.upper = c;
    136             this.lower = 0x0069;
    137             return this;
    138         }
    139         if ( c == 0x0131 ) {
    140             this.upper = 0x0049;
    141             this.lower = c;
    142             return this;
    143         }
    144 
    145         if ( c % 2 == 0 ) {
    146         // if it's even, it's a capital and the lower case is c +1
    147             this.upper = c;
    148             this.lower = c+1;
    149         } else {
    150         // if it's odd, it's a lower case and upper case is c-1
    151             this.upper = c-1;
    152             this.lower = c;
    153         }
    154         return this;
    155     }
    156     if ( c == 0x0178 ) {
    157         this.upper = c;
    158         this.lower = 0x00FF;
    159         return this;
    160     }
    161 
    162     if ( (c >= 0x0139 && c < 0x0149) || (c > 0x0178 && c < 0x017F) ) {
    163         if ( c % 2 == 1 ) {
    164         // if it's odd, it's a capital and the lower case is c +1
    165             this.upper = c;
    166             this.lower = c+1;
    167         } else {
    168         // if it's even, it's a lower case and upper case is c-1
    169             this.upper = c-1;
    170             this.lower = c;
    171         }
    172         return this;
    173     }
    174     if ( c == 0x017F ) {
    175         this.upper = 0x0053;
    176         this.lower = c;
    177     }
    178 
    179     // Latin Extended B
    180     // need to improve this set
    181 
    182     if ( c >= 0x0200 && c <= 0x0217 ) {
    183         if ( c % 2 == 0 ) {
    184             this.upper = c;
    185             this.lower = c+1;
    186         } else {
    187             this.upper = c-1;
    188             this.lower = c;
    189         }
    190         return this;
    191     }
    192 
    193     // Latin Extended Additional
    194     // Range: U+1E00 to U+1EFF
    195     // http://www.unicode.org/Unicode.charts/glyphless/U1E00.html
    196 
    197     // Spacing Modifier Leters
    198     // Range: U+02B0 to U+02FF
    199 
    200     // Combining Diacritical Marks
    201     // Range: U+0300 to U+036F
    202 
    203     // skip Greek for now
    204     // Greek
    205     // Range: U+0370 to U+03FF
    206 
    207     // Cyrillic
    208     // Range: U+0400 to U+04FF
    209 
    210     if ( (c >= 0x0401 && c <= 0x040C) || ( c>= 0x040E && c <= 0x040F ) ) {
    211         this.upper = c;
    212         this.lower = c + 80;
    213         return this;
    214     }
    215 
    216 
    217     if ( c >= 0x0410  && c <= 0x042F ) {
    218         this.upper = c;
    219         this.lower = c + 32;
    220         return this;
    221     }
    222 
    223     if ( c >= 0x0430 && c<= 0x044F ) {
    224         this.upper = c - 32;
    225         this.lower = c;
    226         return this;
    227 
    228     }
    229     if ( (c >= 0x0451 && c <= 0x045C) || (c >=0x045E && c<= 0x045F) ) {
    230         this.upper = c -80;
    231         this.lower = c;
    232         return this;
    233     }
    234 
    235     if ( c >= 0x0460 && c <= 0x047F ) {
    236         if ( c % 2 == 0 ) {
    237             this.upper = c;
    238             this.lower = c +1;
    239         } else {
    240             this.upper = c - 1;
    241             this.lower = c;
    242         }
    243         return this;
    244     }
    245 
    246     // Armenian
    247     // Range: U+0530 to U+058F
    248     if ( c >= 0x0531 && c <= 0x0556 ) {
    249         this.upper = c;
    250         this.lower = c + 48;
    251         return this;
    252     }
    253     if ( c >= 0x0561 && c < 0x0587 ) {
    254         this.upper = c - 48;
    255         this.lower = c;
    256         return this;
    257     }
    258 
    259     // Hebrew
    260     // Range: U+0590 to U+05FF
    261 
    262 
    263     // Arabic
    264     // Range: U+0600 to U+06FF
    265 
    266     // Devanagari
    267     // Range: U+0900 to U+097F
    268 
    269 
    270     // Bengali
    271     // Range: U+0980 to U+09FF
    272 
    273 
    274     // Gurmukhi
    275     // Range: U+0A00 to U+0A7F
    276 
    277 
    278     // Gujarati
    279     // Range: U+0A80 to U+0AFF
    280 
    281 
    282     // Oriya
    283     // Range: U+0B00 to U+0B7F
    284     // no capital / lower case
    285 
    286 
    287     // Tamil
    288     // Range: U+0B80 to U+0BFF
    289     // no capital / lower case
    290 
    291 
    292     // Telugu
    293     // Range: U+0C00 to U+0C7F
    294     // no capital / lower case
    295 
    296 
    297     // Kannada
    298     // Range: U+0C80 to U+0CFF
    299     // no capital / lower case
    300 
    301 
    302     // Malayalam
    303     // Range: U+0D00 to U+0D7F
    304 
    305     // Thai
    306     // Range: U+0E00 to U+0E7F
    307 
    308 
    309     // Lao
    310     // Range: U+0E80 to U+0EFF
    311 
    312 
    313     // Tibetan
    314     // Range: U+0F00 to U+0FBF
    315 
    316     // Georgian
    317     // Range: U+10A0 to U+10F0
    318     if ( c >= 0x10A0 && c <= 0x10C5 ) {
    319         this.upper = c;
    320         this.lower = c + 48;
    321         return this;
    322     }
    323     if ( c >= 0x10D0 && c <= 0x10F5 ) {
    324         this.upper = c;
    325         this.lower = c;
    326         return this;
    327     }
    328 
    329     // Hangul Jamo
    330     // Range: U+1100 to U+11FF
    331 
    332     // Greek Extended
    333     // Range: U+1F00 to U+1FFF
    334     // skip for now
    335 
    336 
    337     // General Punctuation
    338     // Range: U+2000 to U+206F
    339 
    340     // Superscripts and Subscripts
    341     // Range: U+2070 to U+209F
    342 
    343     // Currency Symbols
    344     // Range: U+20A0 to U+20CF
    345 
    346 
    347     // Combining Diacritical Marks for Symbols
    348     // Range: U+20D0 to U+20FF
    349     // skip for now
    350 
    351 
    352     // Number Forms
    353     // Range: U+2150 to U+218F
    354     // skip for now
    355 
    356 
    357     // Arrows
    358     // Range: U+2190 to U+21FF
    359 
    360     // Mathematical Operators
    361     // Range: U+2200 to U+22FF
    362 
    363     // Miscellaneous Technical
    364     // Range: U+2300 to U+23FF
    365 
    366     // Control Pictures
    367     // Range: U+2400 to U+243F
    368 
    369     // Optical Character Recognition
    370     // Range: U+2440 to U+245F
    371 
    372     // Enclosed Alphanumerics
    373     // Range: U+2460 to U+24FF
    374 
    375     // Box Drawing
    376     // Range: U+2500 to U+257F
    377 
    378     // Block Elements
    379     // Range: U+2580 to U+259F
    380 
    381     // Geometric Shapes
    382     // Range: U+25A0 to U+25FF
    383 
    384     // Miscellaneous Symbols
    385     // Range: U+2600 to U+26FF
    386 
    387     // Dingbats
    388     // Range: U+2700 to U+27BF
    389 
    390     // CJK Symbols and Punctuation
    391     // Range: U+3000 to U+303F
    392 
    393     // Hiragana
    394     // Range: U+3040 to U+309F
    395 
    396     // Katakana
    397     // Range: U+30A0 to U+30FF
    398 
    399     // Bopomofo
    400     // Range: U+3100 to U+312F
    401 
    402     // Hangul Compatibility Jamo
    403     // Range: U+3130 to U+318F
    404 
    405     // Kanbun
    406     // Range: U+3190 to U+319F
    407 
    408 
    409     // Enclosed CJK Letters and Months
    410     // Range: U+3200 to U+32FF
    411 
    412     // CJK Compatibility
    413     // Range: U+3300 to U+33FF
    414 
    415     // Hangul Syllables
    416     // Range: U+AC00 to U+D7A3
    417 
    418     // High Surrogates
    419     // Range: U+D800 to U+DB7F
    420 
    421     // Private Use High Surrogates
    422     // Range: U+DB80 to U+DBFF
    423 
    424     // Low Surrogates
    425     // Range: U+DC00 to U+DFFF
    426 
    427     // Private Use Area
    428     // Range: U+E000 to U+F8FF
    429 
    430     // CJK Compatibility Ideographs
    431     // Range: U+F900 to U+FAFF
    432 
    433     // Alphabetic Presentation Forms
    434     // Range: U+FB00 to U+FB4F
    435 
    436     // Arabic Presentation Forms-A
    437     // Range: U+FB50 to U+FDFF
    438 
    439     // Combining Half Marks
    440     // Range: U+FE20 to U+FE2F
    441 
    442     // CJK Compatibility Forms
    443     // Range: U+FE30 to U+FE4F
    444 
    445     // Small Form Variants
    446     // Range: U+FE50 to U+FE6F
    447 
    448     // Arabic Presentation Forms-B
    449     // Range: U+FE70 to U+FEFF
    450 
    451     // Halfwidth and Fullwidth Forms
    452     // Range: U+FF00 to U+FFEF
    453 
    454     if ( c >= 0xFF21 && c <= 0xFF3A ) {
    455         this.upper = c;
    456         this.lower = c + 32;
    457         return this;
    458     }
    459 
    460     if ( c >= 0xFF41 && c <= 0xFF5A ) {
    461         this.upper = c - 32;
    462         this.lower = c;
    463         return this;
    464     }
    465 
    466     // Specials
    467     // Range: U+FFF0 to U+FFFF
    468 
    469     return this;
    470 }
    471 
    472 function DecimalToHexString( n ) {
    473     n = Number( n );
    474     var h = "0x";
    475 
    476     for ( var i = 3; i >= 0; i-- ) {
    477         if ( n >= Math.pow(16, i) ){
    478             var t = Math.floor( n  / Math.pow(16, i));
    479             n -= t * Math.pow(16, i);
    480             if ( t >= 10 ) {
    481                 if ( t == 10 ) {
    482                     h += "A";
    483                 }
    484                 if ( t == 11 ) {
    485                     h += "B";
    486                 }
    487                 if ( t == 12 ) {
    488                     h += "C";
    489                 }
    490                 if ( t == 13 ) {
    491                     h += "D";
    492                 }
    493                 if ( t == 14 ) {
    494                     h += "E";
    495                 }
    496                 if ( t == 15 ) {
    497                     h += "F";
    498                 }
    499             } else {
    500                 h += String( t );
    501             }
    502         } else {
    503             h += "0";
    504         }
    505     }
    506 
    507     return h;
    508 }