Created
September 6, 2012 10:43
-
-
Save marianoguerra/3654677 to your computer and use it in GitHub Desktop.
fix for one-color #11
This file contains 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
//taken from es5shim | |
(function () { | |
if (!Function.prototype.bind) { | |
Function.prototype.bind = function bind(that) { // .length is 1 | |
// 1. Let Target be the this value. | |
var target = this; | |
// 2. If IsCallable(Target) is false, throw a TypeError exception. | |
if (typeof target != "function") { | |
throw new TypeError("Function.prototype.bind called on incompatible " + target); | |
} | |
// 3. Let A be a new (possibly empty) internal list of all of the | |
// argument values provided after thisArg (arg1, arg2 etc), in order. | |
// XXX slicedArgs will stand in for "A" if used | |
var args = slice.call(arguments, 1); // for normal call | |
// 4. Let F be a new native ECMAScript object. | |
// 11. Set the [[Prototype]] internal property of F to the standard | |
// built-in Function prototype object as specified in 15.3.3.1. | |
// 12. Set the [[Call]] internal property of F as described in | |
// 15.3.4.5.1. | |
// 13. Set the [[Construct]] internal property of F as described in | |
// 15.3.4.5.2. | |
// 14. Set the [[HasInstance]] internal property of F as described in | |
// 15.3.4.5.3. | |
var bound = function () { | |
if (this instanceof bound) { | |
// 15.3.4.5.2 [[Construct]] | |
// When the [[Construct]] internal method of a function object, | |
// F that was created using the bind function is called with a | |
// list of arguments ExtraArgs, the following steps are taken: | |
// 1. Let target be the value of F's [[TargetFunction]] | |
// internal property. | |
// 2. If target has no [[Construct]] internal method, a | |
// TypeError exception is thrown. | |
// 3. Let boundArgs be the value of F's [[BoundArgs]] internal | |
// property. | |
// 4. Let args be a new list containing the same values as the | |
// list boundArgs in the same order followed by the same | |
// values as the list ExtraArgs in the same order. | |
// 5. Return the result of calling the [[Construct]] internal | |
// method of target providing args as the arguments. | |
var F = function(){}; | |
F.prototype = target.prototype; | |
var self = new F; | |
var result = target.apply( | |
self, | |
args.concat(slice.call(arguments)) | |
); | |
if (Object(result) === result) { | |
return result; | |
} | |
return self; | |
} else { | |
// 15.3.4.5.1 [[Call]] | |
// When the [[Call]] internal method of a function object, F, | |
// which was created using the bind function is called with a | |
// this value and a list of arguments ExtraArgs, the following | |
// steps are taken: | |
// 1. Let boundArgs be the value of F's [[BoundArgs]] internal | |
// property. | |
// 2. Let boundThis be the value of F's [[BoundThis]] internal | |
// property. | |
// 3. Let target be the value of F's [[TargetFunction]] internal | |
// property. | |
// 4. Let args be a new list containing the same values as the | |
// list boundArgs in the same order followed by the same | |
// values as the list ExtraArgs in the same order. | |
// 5. Return the result of calling the [[Call]] internal method | |
// of target providing boundThis as the this value and | |
// providing args as the arguments. | |
// equiv: target.call(this, ...boundArgs, ...args) | |
return target.apply( | |
that, | |
args.concat(slice.call(arguments)) | |
); | |
} | |
}; | |
// XXX bound.length is never writable, so don't even try | |
// | |
// 15. If the [[Class]] internal property of Target is "Function", then | |
// a. Let L be the length property of Target minus the length of A. | |
// b. Set the length own property of F to either 0 or L, whichever is | |
// larger. | |
// 16. Else set the length own property of F to 0. | |
// 17. Set the attributes of the length own property of F to the values | |
// specified in 15.3.5.1. | |
// TODO | |
// 18. Set the [[Extensible]] internal property of F to true. | |
// TODO | |
// 19. Let thrower be the [[ThrowTypeError]] function Object (13.2.3). | |
// 20. Call the [[DefineOwnProperty]] internal method of F with | |
// arguments "caller", PropertyDescriptor {[[Get]]: thrower, [[Set]]: | |
// thrower, [[Enumerable]]: false, [[Configurable]]: false}, and | |
// false. | |
// 21. Call the [[DefineOwnProperty]] internal method of F with | |
// arguments "arguments", PropertyDescriptor {[[Get]]: thrower, | |
// [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: false}, | |
// and false. | |
// TODO | |
// NOTE Function objects created using Function.prototype.bind do not | |
// have a prototype property or the [[Code]], [[FormalParameters]], and | |
// [[Scope]] internal properties. | |
// XXX can't delete prototype in pure-js. | |
// 22. Return F. | |
return bound; | |
}; | |
} | |
// Shortcut to an often accessed properties, in order to avoid multiple | |
// dereference that costs universally. | |
// _Please note: Shortcuts are defined after `Function.prototype.bind` as we | |
// us it in defining shortcuts. | |
var call = Function.prototype.call; | |
var prototypeOfArray = Array.prototype; | |
var prototypeOfObject = Object.prototype; | |
var slice = prototypeOfArray.slice; | |
// Having a toString local variable name breaks in Opera so use _toString. | |
var _toString = call.bind(prototypeOfObject.toString); | |
var owns = call.bind(prototypeOfObject.hasOwnProperty); | |
// | |
// Array | |
// ===== | |
// | |
// The IsCallable() check in the Array functions | |
// has been replaced with a strict check on the | |
// internal class of the object to trap cases where | |
// the provided function was actually a regular | |
// expression literal, which in V8 and | |
// JavaScriptCore is a typeof "function". Only in | |
// V8 are regular expression literals permitted as | |
// reduce parameters, so it is desirable in the | |
// general case for the shim to match the more | |
// strict and common behavior of rejecting regular | |
// expressions. | |
// ES5 15.4.4.18 | |
// http://es5.github.com/#x15.4.4.18 | |
// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/forEach | |
if (!Array.prototype.forEach) { | |
Array.prototype.forEach = function forEach(fun /*, thisp*/) { | |
var self = toObject(this), | |
thisp = arguments[1], | |
i = -1, | |
length = self.length >>> 0; | |
// If no callback function or if callback is not a callable function | |
if (_toString(fun) != "[object Function]") { | |
throw new TypeError(); // TODO message | |
} | |
while (++i < length) { | |
if (i in self) { | |
// Invoke the callback function with call, passing arguments: | |
// context, property value, property key, thisArg object context | |
fun.call(thisp, self[i], i, self); | |
} | |
} | |
}; | |
} | |
// ES5 15.4.4.19 | |
// http://es5.github.com/#x15.4.4.19 | |
// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map | |
if (!Array.prototype.map) { | |
Array.prototype.map = function map(fun /*, thisp*/) { | |
var self = toObject(this), | |
length = self.length >>> 0, | |
result = Array(length), | |
thisp = arguments[1]; | |
// If no callback function or if callback is not a callable function | |
if (_toString(fun) != "[object Function]") { | |
throw new TypeError(fun + " is not a function"); | |
} | |
for (var i = 0; i < length; i++) { | |
if (i in self) | |
result[i] = fun.call(thisp, self[i], i, self); | |
} | |
return result; | |
}; | |
} | |
// ES5 15.4.4.20 | |
// http://es5.github.com/#x15.4.4.20 | |
// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter | |
if (!Array.prototype.filter) { | |
Array.prototype.filter = function filter(fun /*, thisp */) { | |
var self = toObject(this), | |
length = self.length >>> 0, | |
result = [], | |
value, | |
thisp = arguments[1]; | |
// If no callback function or if callback is not a callable function | |
if (_toString(fun) != "[object Function]") { | |
throw new TypeError(fun + " is not a function"); | |
} | |
for (var i = 0; i < length; i++) { | |
if (i in self) { | |
value = self[i]; | |
if (fun.call(thisp, value, i, self)) { | |
result.push(value); | |
} | |
} | |
} | |
return result; | |
}; | |
} | |
// | |
// Util | |
// ====== | |
// | |
var prepareString = "a"[0] != "a"; | |
// ES5 9.9 | |
// http://es5.github.com/#x9.9 | |
var toObject = function (o) { | |
if (o == null) { // this matches both null and undefined | |
throw new TypeError("can't convert "+o+" to object"); | |
} | |
// If the implementation doesn't support by-index access of | |
// string characters (ex. IE < 9), split the string | |
if (prepareString && typeof o == "string" && o) { | |
return o.split(""); | |
} | |
return Object(o); | |
}; | |
}()); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment