Created
August 12, 2011 17:29
-
-
Save bryanforbes/1142512 to your computer and use it in GitHub Desktop.
Dojo es5-shim for 2.0
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| define(["./has"], function(has){ | |
| // An ES5 shim for older browsers for Dojo 2.0. | |
| // Please note that this is much larger than dojo/array in 1.7 for a few reasons: | |
| // * Feature tests | |
| // * Addition of Array#reduce, Array#reduceRight, Function#bind | |
| var ap = Array.prototype, | |
| fp = Function.prototype; | |
| has.add("array-indexof", !!ap.indexOf); | |
| has.add("array-foreach", !!ap.forEach); | |
| has.add("array-every", !!ap.every); | |
| has.add("array-reduce", !!ap.reduce); | |
| has.add("array-isarray", !!Array.isArray); | |
| has.add("function-bind", !!fp.bind); | |
| function ToInteger(value){ | |
| // From John David Dalton. | |
| value = +value; | |
| return (value === 0 || !isFinite(value)) ? | |
| (value || 0) : | |
| ((value > 0 || -1) * Math.floor(Math.abs(value))); | |
| } | |
| function prep(o){ | |
| // If it's a string, determine if we have to call split on it | |
| if(typeof o == "string" && o && !(0 in o)){ | |
| return o.split(""); | |
| } | |
| return o; | |
| } | |
| // NOTE: `o.length >>> 0` applies the same length constraints to array-like objects | |
| // as are applied to arrays (Math.pow(2, 32) - 1). | |
| var u; | |
| function index(up){ | |
| var delta = 1, over = 0; | |
| if(!up){ | |
| delta = over = -1; | |
| } | |
| return function(value){ | |
| var o = prep(this), | |
| fromIndex = arguments[1], | |
| len = o.length >>> 0, | |
| end = up ? len + 0 : -1, | |
| k; | |
| if(len === 0){ return -1; } | |
| if(fromIndex === u){ | |
| k = up ? 0 : len - 1; | |
| }else{ | |
| fromIndex = ToInteger(fromIndex); | |
| if(fromIndex < 0){ | |
| k = len + fromIndex; | |
| if(k < 0){ | |
| k = 0; | |
| } | |
| }else{ | |
| k = fromIndex >= len ? len + over : fromIndex; | |
| } | |
| } | |
| for(; k!=end; k += delta){ | |
| if((k in o) && o[k] === value){ | |
| return k; | |
| } | |
| } | |
| return -1; | |
| }; | |
| } | |
| if(!has("array-indexof")){ | |
| ap.indexOf = index(true); | |
| ap.lastIndexOf = index(false); | |
| } | |
| function everyOrSome(some){ | |
| var every = !some; | |
| return function(callback){ | |
| var o = prep(this), | |
| thisArg = arguments[1], | |
| len = o.length >>> 0, | |
| k = -1, result; | |
| if(thisArg){ | |
| while(++k<len){ | |
| if((k in o) && (some ^ (result = !callback.call(thisArg, o[k], k, o)))){ | |
| return !result; | |
| } | |
| } | |
| }else{ | |
| while(++k<len){ | |
| if((k in o) && (some ^ (result = !callback(o[k], k, o)))){ | |
| return !result; | |
| } | |
| } | |
| } | |
| return every; | |
| }; | |
| } | |
| if(!has("array-every")){ | |
| ap.every = everyOrSome(false); | |
| ap.some = everyOrSome(true); | |
| } | |
| if(!has("array-foreach")){ | |
| ap.forEach = function forEach(callback){ | |
| var o = prep(this), | |
| thisArg = arguments[1], | |
| len = o.length >>> 0, | |
| k = -1; | |
| if(thisArg){ | |
| while(++k<len){ | |
| (k in o) && callback.call(thisArg, o[k], k, o); | |
| } | |
| }else{ | |
| while(++k<len){ | |
| (k in o) && callback(o[k], k, o); | |
| } | |
| } | |
| }; | |
| ap.map = function map(callback){ | |
| var o = prep(this), | |
| thisArg = arguments[1], | |
| len = o.length >>> 0, | |
| arr = Array(len), | |
| k = -1; | |
| if(thisArg){ | |
| while(++k<len){ | |
| (k in o) && (arr[k] = callback.call(thisArg, o[k], k, o)); | |
| } | |
| }else{ | |
| while(++k<len){ | |
| (k in o) && (arr[k] = callback(o[k], k, o)); | |
| } | |
| } | |
| return arr; | |
| }; | |
| ap.filter = function filter(callback){ | |
| var o = prep(this), | |
| thisArg = arguments[1], | |
| len = o.length >>> 0, | |
| arr = [], | |
| k = -1, | |
| kValue; | |
| if(thisArg){ | |
| while(++k<len){ | |
| kValue = o[k]; | |
| (k in o) && !!callback.call(thisArg, kValue, k, o) && arr.push(kValue); | |
| } | |
| }else{ | |
| while(++k<len){ | |
| kValue = o[k]; | |
| (k in o) && !!callback(kValue, k, o) && arr.push(kValue); | |
| } | |
| } | |
| return arr; | |
| }; | |
| } | |
| function reduce(left){ | |
| var delta = 1; | |
| if(!left){ | |
| delta = -1; | |
| } | |
| return function(callback){ | |
| var o = prep(this), | |
| initialValue = arguments[1], | |
| len = o.length >>> 0, | |
| k, end, acc; | |
| if(len === 0 && arguments.length < 2){ | |
| throw new Error(); | |
| } | |
| k = left ? 0 : len - 1; | |
| end = left ? len : -1; | |
| if(initialValue !== u){ | |
| acc = initialValue; | |
| }else{ | |
| var kPresent = false; | |
| for(;!kPresent && k!=end; k+=delta){ | |
| (kPresent = (k in o)) && (acc = o[k]); | |
| } | |
| if(!kPresent){ | |
| throw new Error(); | |
| } | |
| } | |
| for(;k!=end; k+=delta){ | |
| (k in o) && (acc = callback(acc, o[k], k, o)); | |
| } | |
| return acc; | |
| }; | |
| } | |
| if(!has("array-reduce")){ | |
| ap.reduce = reduce(true); | |
| ap.reduceRight = reduce(false); | |
| } | |
| if(!has("array-isarray")){ | |
| var toString = Object.prototype.toString; | |
| Array.isArray = function isArray(arr){ | |
| return toString.call(arr) == "[object Array]"; | |
| }; | |
| } | |
| if(!has("function-bind")){ | |
| var delegate = (function(){ | |
| // boodman/crockford delegation w/ cornford optimization | |
| function TMP(){} | |
| return function(obj, props){ | |
| TMP.prototype = obj; | |
| var tmp = new TMP(); | |
| TMP.prototype = null; | |
| return tmp; // Object | |
| }; | |
| })(); | |
| var slice = ap.slice; | |
| fp.bind = function bind(scope){ | |
| var pre = slice.call(arguments, 1), f = this; | |
| function b(){ | |
| var args = pre.concat(slice.call(arguments)); | |
| obj = scope; | |
| return (this instanceof b) ? | |
| (f.apply((obj = delegate(f.prototype)), args) || obj) : | |
| f.apply(obj, args); | |
| } | |
| // override .call and .apply so passing in an instance of | |
| // "b" as newScope won't trigger an incorrect response | |
| b.call = function(newScope){ | |
| f.apply(scope, pre.concat(slice.call(arguments, 1))); | |
| }; | |
| b.apply = function(newScope, args){ | |
| f.apply(scope, pre.concat(args)); | |
| }; | |
| return b; | |
| }; | |
| } | |
| }); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment