1 /*global JXG: true, define: true, escape: true, unescape: true*/ 2 /*jslint nomen: true, plusplus: true, bitwise: true*/ 3 4 /* depends: 5 jxg 6 */ 7 8 define(['jxg'], function (JXG) { 9 10 "use strict"; 11 12 // constants 13 var UTF8_ACCEPT = 0, 14 UTF8_REJECT = 12, 15 UTF8D = [ 16 // The first part of the table maps bytes to character classes that 17 // to reduce the size of the transition table and create bitmasks. 18 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 23 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 24 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 25 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 3, 11, 6, 6, 6, 5, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 26 27 // The second part is a transition table that maps a combination 28 // of a state of the automaton and a character class to a state. 29 0, 12, 24, 36, 60, 96, 84, 12, 12, 12, 48, 72, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 30 12, 0, 12, 12, 12, 12, 12, 0, 12, 0, 12, 12, 12, 24, 12, 12, 12, 12, 12, 24, 12, 24, 12, 12, 31 12, 12, 12, 12, 12, 12, 12, 24, 12, 12, 12, 12, 12, 24, 12, 12, 12, 12, 12, 12, 12, 24, 12, 12, 32 12, 12, 12, 12, 12, 12, 12, 36, 12, 36, 12, 12, 12, 36, 12, 12, 12, 12, 12, 36, 12, 36, 12, 12, 33 12, 36, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12 34 ]; 35 36 // Util namespace 37 JXG.Util = JXG.Util || {}; 38 39 /** 40 * UTF8 encoding routines 41 * @namespace 42 */ 43 JXG.Util.UTF8 = { 44 /** 45 * Encode a string to utf-8. 46 * @param {String} string 47 * @return {String} utf8 encoded string 48 */ 49 encode : function (string) { 50 var n, c, 51 utftext = '', 52 len = string.length; 53 54 string = string.replace(/\r\n/g, '\n'); 55 56 // See 57 // http://ecmanaut.blogspot.ca/2006/07/encoding-decoding-utf8-in-javascript.html 58 // http://monsur.hossa.in/2012/07/20/utf-8-in-javascript.html 59 if (typeof unescape === 'function' && typeof encodeURIComponent === 'function') { 60 return unescape(encodeURIComponent(string)); 61 } 62 63 for (n = 0; n < len; n++) { 64 c = string.charCodeAt(n); 65 66 if (c < 128) { 67 utftext += String.fromCharCode(c); 68 } else if ((c > 127) && (c < 2048)) { 69 utftext += String.fromCharCode((c >> 6) | 192); 70 utftext += String.fromCharCode((c & 63) | 128); 71 } else { 72 utftext += String.fromCharCode((c >> 12) | 224); 73 utftext += String.fromCharCode(((c >> 6) & 63) | 128); 74 utftext += String.fromCharCode((c & 63) | 128); 75 } 76 77 } 78 79 return utftext; 80 }, 81 82 /** 83 * Decode a string from utf-8. 84 * @param {String} utftext to decode 85 * @return {String} utf8 decoded string 86 */ 87 decode : function (utftext) { 88 /* 89 The following code is a translation from C99 to JavaScript. 90 91 The original C99 code can be found at 92 http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ 93 94 Original copyright note: 95 96 Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de> 97 98 License: MIT License (see LICENSE.MIT) 99 */ 100 101 var i, charCode, type, 102 j = 0, 103 codepoint = 0, 104 state = UTF8_ACCEPT, 105 chars = [], 106 len = utftext.length, 107 results = []; 108 109 for (i = 0; i < len; i++) { 110 charCode = utftext.charCodeAt(i); 111 type = UTF8D[charCode]; 112 113 if (state !== UTF8_ACCEPT) { 114 codepoint = (charCode & 0x3f) | (codepoint << 6); 115 } else { 116 codepoint = (0xff >> type) & charCode; 117 } 118 119 state = UTF8D[256 + state + type]; 120 121 if (state === UTF8_ACCEPT) { 122 if (codepoint > 0xffff) { 123 chars.push(0xD7C0 + (codepoint >> 10), 0xDC00 + (codepoint & 0x3FF)); 124 } else { 125 chars.push(codepoint); 126 } 127 128 j++; 129 130 if (j % 10000 === 0) { 131 results.push(String.fromCharCode.apply(null, chars)); 132 chars = []; 133 } 134 } 135 } 136 results.push(String.fromCharCode.apply(null, chars)); 137 return results.join(""); 138 }, 139 140 /** 141 * Extends the standard charCodeAt() method of the String class to find the ASCII char code of 142 * a character at a given position in a UTF8 encoded string. 143 * @param {String} str 144 * @param {Number} i position of the character 145 * @return {Number} 146 */ 147 asciiCharCodeAt: function (str, i) { 148 var c = str.charCodeAt(i); 149 150 if (c > 255) { 151 switch (c) { 152 case 8364: 153 c = 128; 154 break; 155 case 8218: 156 c = 130; 157 break; 158 case 402: 159 c = 131; 160 break; 161 case 8222: 162 c = 132; 163 break; 164 case 8230: 165 c = 133; 166 break; 167 case 8224: 168 c = 134; 169 break; 170 case 8225: 171 c = 135; 172 break; 173 case 710: 174 c = 136; 175 break; 176 case 8240: 177 c = 137; 178 break; 179 case 352: 180 c = 138; 181 break; 182 case 8249: 183 c = 139; 184 break; 185 case 338: 186 c = 140; 187 break; 188 case 381: 189 c = 142; 190 break; 191 case 8216: 192 c = 145; 193 break; 194 case 8217: 195 c = 146; 196 break; 197 case 8220: 198 c = 147; 199 break; 200 case 8221: 201 c = 148; 202 break; 203 case 8226: 204 c = 149; 205 break; 206 case 8211: 207 c = 150; 208 break; 209 case 8212: 210 c = 151; 211 break; 212 case 732: 213 c = 152; 214 break; 215 case 8482: 216 c = 153; 217 break; 218 case 353: 219 c = 154; 220 break; 221 case 8250: 222 c = 155; 223 break; 224 case 339: 225 c = 156; 226 break; 227 case 382: 228 c = 158; 229 break; 230 case 376: 231 c = 159; 232 break; 233 default: 234 break; 235 } 236 } 237 return c; 238 } 239 }; 240 241 return JXG.Util.UTF8; 242 }); 243