(function(_Object, _Array, _Function){
-var P = "prototype"
-, AP = _Array[P]
-, FP = _Function[P]
-, slice = AP.slice
-, objToString = _Object[P].toString
+var P = "prototype"
+, FP = _Function[P]
+
+, AP = _Array[P]
+, _slice = AP.slice
+
+, OP = _Object[P]
+, hasOwn = OP.hasOwnProperty
+, getget = OP.__lookupGetter__
+, getset = OP.__lookupSetter__
+, setget = OP.__defineGetter__
+, setset = OP.__defineSetter__
+, objToString = OP.toString
;
if ( !_Array.slice ) {
_Array.slice = function slice(a){
- return slice.apply(a, slice.call(arguments, 1));
+ return _slice.apply(a, _slice.call(arguments, 1));
};
}
}
}
-
+if ( !_Array.isArray ) {
+ _Array.isArray = function isArray(o) { return objToString.call(o) === '[object Array]'; };
+}
// JavaScript 1.8.5
if ( !FP.bind ) {
FP.bind = function bind( context ){
var fn = this,
- args = slice.call(arguments, 1);
+ args = _slice.call(arguments,1);
return function(){
- return fn.apply(context, args.concat( slice.call(arguments,0) ));
+ return fn.apply(context, args.concat( _slice.call(arguments,0) ));
};
};
}
if ( !_Object.getPrototypeOf ) {
- _Object.getPrototypeOf =
+ _Object['getPrototypeOf'] =
( (typeof "".__proto__ === "object")
- ? function(object){ return object.__proto__; }
- : function(object){ return object.constructor[P]; }
+ ? function getPrototypeOf(o){ return o.__proto__; }
+ : function getPrototypeOf(o){ return o.constructor[P]; }
);
}
-if ( !_Array.isArray ) {
- _Array.isArray = function isArray(o) { return objToString.call(o) === '[object Array]'; };
+if ( !_Object.keys ) {
+ _Object['keys'] =
+ function keys(o){
+ var k, keys = [];
+ for ( k in o )
+ if (hasOwn.call(o,k)) keys.push(k);
+ return keys;
+ };
+}
+
+if ( !_Object.defineProperty ) {
+
+ function isFunction(f){
+ return typeof f === "function";
+ }
+
+ function cleanDescriptor(desc){
+ if (typeof desc !== "object" || desc === null)
+ throw new TypeError("Property description must be an object: "+desc);
+
+ var d = {}
+ , get = desc.get, set = desc.set
+ , hasValue = hasOwn.call(desc, 'value')
+ ;
+
+ if (hasOwn.call(desc, 'get') && get !== undefined) {
+ if (!isFunction(get))
+ throw new TypeError("Getter must be a function: "+get);
+ d.get = get;
+ }
+
+ if (hasOwn.call(desc, 'set') && set !== undefined) {
+ if (!isFunction(set))
+ throw new TypeError("Setter must be a function: "+set);
+ d.set = set;
+ }
+
+ if ( hasValue && (d.get || d.set) )
+ throw new TypeError("Invalid property. A property cannot both have accessors and be writable or have a value: "+desc);
+
+ if ( hasValue )
+ d.value = desc.value;
+
+ return d;
+ }
+
+ _Object['defineProperty'] =
+ function defineProperty(o, prop, desc){
+ if (typeof o !== "object" || o === null)
+ throw new TypeError("Object.defineProperty called on non-object: "+o);
+
+ desc = cleanDescriptor(desc);
+ if ( 'value' in desc ) {
+ delete o[prop];
+ o[prop] = desc.value;
+ } else {
+ if ( desc.get ) setget.call(o, prop, desc.get);
+ if ( desc.set ) setset.call(o, prop, desc.set);
+ }
+
+ return o;
+ };
+
+ _Object['defineProperties'] =
+ function defineProperties(o, props) {
+ if (typeof o !== "object" || o === null)
+ throw new TypeError("Object.defineProperty called on non-object: "+o);
+
+ props = Object(props);
+ var k, descs = {};
+
+ // Perform all the error checks before mutating anything
+ for (k in props)
+ if (hasOwn.call(props,k)) descs[k] = cleanDescriptor(props[k]);
+
+ // Now we can start changing things
+ for (k in descs)
+ _Object.defineProperty(o, k, descs[k]);
+
+ return o;
+ }
+
+ _Object['getOwnPropertyDescriptor'] =
+ function getOwnPropertyDescriptor(o, prop){
+ if (typeof o !== "object" || o === null)
+ throw new TypeError("Object.getOwnPropertyDescriptor called on non-object: "+o);
+
+ if ( !hasOwn.call(o,prop) )
+ return undefined;
+
+ var getter = getget.call(o, prop)
+ , setter = getset.call(o, prop)
+ , desc = { 'configurable':true, 'enumerable':true };
+
+ // Data Descriptor
+ if (getter === undefined && setter === undefined) {
+ desc['value'] = o[prop];
+ desc['writable'] = true;
+
+ // Accessor Descriptor
+ } else {
+ if (getter) desc['get'] = getter;
+ if (setter) desc['set'] = setter;
+ }
+
+ return desc;
+ };
}
+
})(Object, Array, Function);