From 383756dee9c71ef4d87ea427c4988d33d851b4d1 Mon Sep 17 00:00:00 2001 From: timb Date: Sat, 17 Oct 2015 19:11:25 -0700 Subject: TextEncoder/TextDecoder polyfill for safari --- index.html | 1 + js/vendor/text-encoder-lite.js | 141 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 142 insertions(+) create mode 100644 js/vendor/text-encoder-lite.js diff --git a/index.html b/index.html index bf3504b..4c36fc3 100644 --- a/index.html +++ b/index.html @@ -95,6 +95,7 @@ // lex.opacity = 1 + diff --git a/js/vendor/text-encoder-lite.js b/js/vendor/text-encoder-lite.js new file mode 100644 index 0000000..957fd9b --- /dev/null +++ b/js/vendor/text-encoder-lite.js @@ -0,0 +1,141 @@ +// taken from https://github.com/coolaj86/TextEncoderLite/blob/master/index.js +// added polyfill at bottom + +function TextEncoderLite() { +} +function TextDecoderLite() { +} + +(function () { +'use strict'; + +// Taken from https://github.com/feross/buffer/blob/master/index.js +// Thanks Feross et al! :-) + +function utf8ToBytes (string, units) { + units = units || Infinity + var codePoint + var length = string.length + var leadSurrogate = null + var bytes = [] + var i = 0 + + for (; i < length; i++) { + codePoint = string.charCodeAt(i) + + // is surrogate component + if (codePoint > 0xD7FF && codePoint < 0xE000) { + // last char was a lead + if (leadSurrogate) { + // 2 leads in a row + if (codePoint < 0xDC00) { + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) + leadSurrogate = codePoint + continue + } else { + // valid surrogate pair + codePoint = leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00 | 0x10000 + leadSurrogate = null + } + } else { + // no lead yet + + if (codePoint > 0xDBFF) { + // unexpected trail + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) + continue + } else if (i + 1 === length) { + // unpaired lead + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) + continue + } else { + // valid lead + leadSurrogate = codePoint + continue + } + } + } else if (leadSurrogate) { + // valid bmp char, but last char was a lead + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) + leadSurrogate = null + } + + // encode utf8 + if (codePoint < 0x80) { + if ((units -= 1) < 0) break + bytes.push(codePoint) + } else if (codePoint < 0x800) { + if ((units -= 2) < 0) break + bytes.push( + codePoint >> 0x6 | 0xC0, + codePoint & 0x3F | 0x80 + ) + } else if (codePoint < 0x10000) { + if ((units -= 3) < 0) break + bytes.push( + codePoint >> 0xC | 0xE0, + codePoint >> 0x6 & 0x3F | 0x80, + codePoint & 0x3F | 0x80 + ) + } else if (codePoint < 0x200000) { + if ((units -= 4) < 0) break + bytes.push( + codePoint >> 0x12 | 0xF0, + codePoint >> 0xC & 0x3F | 0x80, + codePoint >> 0x6 & 0x3F | 0x80, + codePoint & 0x3F | 0x80 + ) + } else { + throw new Error('Invalid code point') + } + } + + return bytes +} + +function utf8Slice (buf, start, end) { + var res = '' + var tmp = '' + end = Math.min(buf.length, end || Infinity) + start = start || 0; + + for (var i = start; i < end; i++) { + if (buf[i] <= 0x7F) { + res += decodeUtf8Char(tmp) + String.fromCharCode(buf[i]) + tmp = '' + } else { + tmp += '%' + buf[i].toString(16) + } + } + + return res + decodeUtf8Char(tmp) +} + +function decodeUtf8Char (str) { + try { + return decodeURIComponent(str) + } catch (err) { + return String.fromCharCode(0xFFFD) // UTF 8 invalid char + } +} + +TextEncoderLite.prototype.encode = function (str) { + var result; + + if ('undefined' === typeof Uint8Array) { + result = utf8ToBytes(str); + } else { + result = new Uint8Array(utf8ToBytes(str)); + } + + return result; +}; + +TextDecoderLite.prototype.decode = function (bytes) { + return utf8Slice(bytes, 0, bytes.length); +} + +}()); + +if (typeof TextEncoder === 'undefined') TextEncoder = TextEncoderLite +if (typeof TextDecoder === 'undefined') TextDecoder = TextDecoderLite -- cgit v1.2.3-70-g09d2