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