diff --git a/index.html b/index.html index 26dfea2..36fe0cb 100644 --- a/index.html +++ b/index.html @@ -36,7 +36,8 @@ Use readAsBinaryString: (when available)

 
- + + diff --git a/shim.js b/shim.js new file mode 100644 index 0000000..30740ec --- /dev/null +++ b/shim.js @@ -0,0 +1,343 @@ +// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys +if (!Object.keys) { + Object.keys = (function () { + var hasOwnProperty = Object.prototype.hasOwnProperty, + hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'), + dontEnums = [ + 'toString', + 'toLocaleString', + 'valueOf', + 'hasOwnProperty', + 'isPrototypeOf', + 'propertyIsEnumerable', + 'constructor' + ], + dontEnumsLength = dontEnums.length; + + return function (obj) { + if (typeof obj !== 'object' && typeof obj !== 'function' || obj === null) throw new TypeError('Object.keys called on non-object'); + + var result = []; + + for (var prop in obj) { + if (hasOwnProperty.call(obj, prop)) result.push(prop); + } + + if (hasDontEnumBug) { + for (var i=0; i < dontEnumsLength; i++) { + if (hasOwnProperty.call(obj, dontEnums[i])) result.push(dontEnums[i]); + } + } + return result; + }; + })(); +} + +// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter +if (!Array.prototype.filter) +{ + Array.prototype.filter = function(fun /*, thisp */) + { + "use strict"; + + if (this == null) + throw new TypeError(); + + var t = Object(this); + var len = t.length >>> 0; + if (typeof fun != "function") + throw new TypeError(); + + var res = []; + var thisp = arguments[1]; + for (var i = 0; i < len; i++) + { + if (i in t) + { + var val = t[i]; // in case fun mutates this + if (fun.call(thisp, val, i, t)) + res.push(val); + } + } + + return res; + }; +} + +// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/Trim +if (!String.prototype.trim) { + String.prototype.trim = function () { + return this.replace(/^\s+|\s+$/g, ''); + }; +} + +// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach +if (!Array.prototype.forEach) +{ + Array.prototype.forEach = function(fun /*, thisArg */) + { + "use strict"; + + if (this === void 0 || this === null) + throw new TypeError(); + + var t = Object(this); + var len = t.length >>> 0; + if (typeof fun !== "function") + throw new TypeError(); + + var thisArg = arguments.length >= 2 ? arguments[1] : void 0; + for (var i = 0; i < len; i++) + { + if (i in t) + fun.call(thisArg, t[i], i, t); + } + }; +} + +// Production steps of ECMA-262, Edition 5, 15.4.4.19 +// Reference: http://es5.github.com/#x15.4.4.19 +if (!Array.prototype.map) { + Array.prototype.map = function(callback, thisArg) { + + var T, A, k; + + if (this == null) { + throw new TypeError(" this is null or not defined"); + } + + // 1. Let O be the result of calling ToObject passing the |this| value as the argument. + var O = Object(this); + + // 2. Let lenValue be the result of calling the Get internal method of O with the argument "length". + // 3. Let len be ToUint32(lenValue). + var len = O.length >>> 0; + + // 4. If IsCallable(callback) is false, throw a TypeError exception. + // See: http://es5.github.com/#x9.11 + if (typeof callback !== "function") { + throw new TypeError(callback + " is not a function"); + } + + // 5. If thisArg was supplied, let T be thisArg; else let T be undefined. + if (thisArg) { + T = thisArg; + } + + // 6. Let A be a new array created as if by the expression new Array(len) where Array is + // the standard built-in constructor with that name and len is the value of len. + A = new Array(len); + + // 7. Let k be 0 + k = 0; + + // 8. Repeat, while k < len + while(k < len) { + + var kValue, mappedValue; + + // a. Let Pk be ToString(k). + // This is implicit for LHS operands of the in operator + // b. Let kPresent be the result of calling the HasProperty internal method of O with argument Pk. + // This step can be combined with c + // c. If kPresent is true, then + if (k in O) { + + // i. Let kValue be the result of calling the Get internal method of O with argument Pk. + kValue = O[ k ]; + + // ii. Let mappedValue be the result of calling the Call internal method of callback + // with T as the this value and argument list containing kValue, k, and O. + mappedValue = callback.call(T, kValue, k, O); + + // iii. Call the DefineOwnProperty internal method of A with arguments + // Pk, Property Descriptor {Value: mappedValue, : true, Enumerable: true, Configurable: true}, + // and false. + + // In browsers that support Object.defineProperty, use the following: + // Object.defineProperty(A, Pk, { value: mappedValue, writable: true, enumerable: true, configurable: true }); + + // For best browser support, use the following: + A[ k ] = mappedValue; + } + // d. Increase k by 1. + k++; + } + + // 9. return A + return A; + }; +} + +// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf +if (!Array.prototype.indexOf) { + Array.prototype.indexOf = function (searchElement, fromIndex) { + if ( this === undefined || this === null ) { + throw new TypeError( '"this" is null or not defined' ); + } + + var length = this.length >>> 0; // Hack to convert object.length to a UInt32 + + fromIndex = +fromIndex || 0; + + if (Math.abs(fromIndex) === Infinity) { + fromIndex = 0; + } + + if (fromIndex < 0) { + fromIndex += length; + if (fromIndex < 0) { + fromIndex = 0; + } + } + + for (;fromIndex < length; fromIndex++) { + if (this[fromIndex] === searchElement) { + return fromIndex; + } + } + + return -1; + }; +} +// Based on https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray + +if (! Array.isArray) { + Array.isArray = function(obj) { + return Object.prototype.toString.call(obj) === "[object Array]"; + }; +} + +// https://github.com/ttaubert/node-arraybuffer-slice +// (c) 2013 Tim Taubert +// arraybuffer-slice may be freely distributed under the MIT license. + +"use strict"; + +if (typeof ArrayBuffer !== 'undefined' && !ArrayBuffer.prototype.slice) { + ArrayBuffer.prototype.slice = function (begin, end) { + begin = (begin|0) || 0; + var num = this.byteLength; + end = end === (void 0) ? num : (end|0); + + // Handle negative values. + if (begin < 0) begin += num; + if (end < 0) end += num; + + if (num === 0 || begin >= num || begin >= end) { + return new ArrayBuffer(0); + } + + var length = Math.min(num - begin, end - begin); + var target = new ArrayBuffer(length); + var targetArray = new Uint8Array(target); + targetArray.set(new Uint8Array(this, begin, length)); + return target; + }; +} + +// https://github.com/davidchambers/Base64.js +// (C) 2015 David Chambers +// Base64.js may be freely distributed under the Apache 2.0 License. +;(function () { + + var object = + typeof exports != 'undefined' ? exports : + typeof self != 'undefined' ? self : // #8: web workers + $.global; // #31: ExtendScript + + var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; + + function InvalidCharacterError(message) { + this.message = message; + } + InvalidCharacterError.prototype = new Error; + InvalidCharacterError.prototype.name = 'InvalidCharacterError'; + + // encoder + // [https://gist.github.com/999166] by [https://github.com/nignag] + object.btoa || ( + object.btoa = function (input) { + var str = String(input); + for ( + // initialize result and counter + var block, charCode, idx = 0, map = chars, output = ''; + // if the next str index does not exist: + // change the mapping table to "=" + // check if d has no fractional digits + str.charAt(idx | 0) || (map = '=', idx % 1); + // "8 - idx % 1 * 8" generates the sequence 2, 4, 6, 8 + output += map.charAt(63 & block >> 8 - idx % 1 * 8) + ) { + charCode = str.charCodeAt(idx += 3/4); + if (charCode > 0xFF) { + throw new InvalidCharacterError("'btoa' failed: The string to be encoded contains characters outside of the Latin1 range."); + } + block = block << 8 | charCode; + } + return output; + }); + + // decoder + // [https://gist.github.com/1020396] by [https://github.com/atk] + object.atob || ( + object.atob = function (input) { + var str = String(input).replace(/[=]+$/, ''); // #31: ExtendScript bad parse of /= + if (str.length % 4 == 1) { + throw new InvalidCharacterError("'atob' failed: The string to be decoded is not correctly encoded."); + } + for ( + // initialize result and counters + var bc = 0, bs, buffer, idx = 0, output = ''; + // get next character + buffer = str.charAt(idx++); + // character found in table? initialize bit storage and add its ascii value; + ~buffer && (bs = bc % 4 ? bs * 64 + buffer : buffer, + // and if not first of each 4 characters, + // convert the first 8 bits to one ascii character + bc++ % 4) ? output += String.fromCharCode(255 & bs >> (-2 * bc & 6)) : 0 + ) { + // try to find character in table (0-63, not found => -1) + buffer = chars.indexOf(buffer); + } + return output; + }); +}()); + + +// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString +if (!Date.prototype.toISOString) { + (function() { + + function pad(number) { + if (number < 10) { + return '0' + number; + } + return number; + } + + Date.prototype.toISOString = function() { + return this.getUTCFullYear() + + '-' + pad(this.getUTCMonth() + 1) + + '-' + pad(this.getUTCDate()) + + 'T' + pad(this.getUTCHours()) + + ':' + pad(this.getUTCMinutes()) + + ':' + pad(this.getUTCSeconds()) + + '.' + (this.getUTCMilliseconds() / 1000).toFixed(3).slice(2, 5) + + 'Z'; + }; + + }()); +} + +// note: MDN shim will not work in IE +if(typeof Uint8Array !== 'undefined' && !Uint8Array.prototype.slice) Uint8Array.prototype.slice = function(start, end) { + if(start < 0) { start += this.length; if(start < 0) start = 0; } + if(start >= this.length) return new Uint8Array(0); + if(end == null) end = this.length; + if(end < 0) { end += this.length; if(end < 0) end = 0; } + if(end > this.length) end = this.length; + var out = new Uint8Array(end - start); + while(start <= --end) out[end - start] = this[end]; + return out; +};