UNPKG

neuronjs

Version:

Neuron is A Full Feature CommonJS Module Manager, Dependency Graph Handler and Loader for Browsers

333 lines (254 loc) 7.44 kB
// ## ECMAScript5 implementation ////////////////////////////////////////////////////////////////////// // - methods native object implemented // - methods native object extends // codes from mootools, MDC or by Kael Zhang // ## Indexes // ### Array.prototype // - indexOf // - lastIndexOf // - filter // - forEach // - every // - map // - some // - reduce // - reduceRight // ### Object // - keys // - create: removed // ### String.prototype // - trim // - trimLeft // - trimRight // ## Specification // ### STANDALONE language enhancement // - always has no dependencies on Neuron // - always follow ECMA standard strictly, including logic, exception type // - throw the same error hint as webkit on a certain exception function extend(host, methods) { for (var name in methods) { if (!host[name]) { host[name] = methods[name]; } } } function implement(host, methods) { extend(host.prototype, methods); } var TYPE_ERROR = TypeError; // ref: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array implement(Array, { // Accessor methods ------------------------ indexOf: function(value, from) { var len = this.length >>> 0; from = Number(from) || 0; from = Math[from < 0 ? 'ceil' : 'floor'](from); if (from < 0) { from = Math.max(from + len, 0); } for (; from < len; from++) { if (from in this && this[from] === value) { return from; } } return -1; }, lastIndexOf: function(value, from) { var len = this.length >>> 0; from = Number(from) || len - 1; from = Math[from < 0 ? 'ceil' : 'floor'](from); if (from < 0) { from += len; } from = Math.min(from, len - 1); for (; from >= 0; from--) { if (from in this && this[from] === value) { return from; } } return -1; }, // Iteration methods ----------------------- filter: function(fn, thisObject) { var ret = []; for (var i = 0, len = this.length; i < len; i++) { // Kael: // Some people might ask: "why we use a `i in this` here?". // ECMA: // > callback is invoked only for indexes of the array which have assigned values; // > it is not invoked for indexes which have been deleted or which have never been assigned values // Besides, `filter` method is not always used with real Arrays, invocations below might happen: // var obj = {length: 4}; obj[3] = 1; // Array.prototype.filter.call({length: 4}); // Array.prototype.filter.call($('body')); // as well as the lines below if ((i in this) && fn.call(thisObject, this[i], i, this)) { ret.push(this[i]); } } return ret; }, forEach: function(fn, thisObject) { for (var i = 0, len = this.length; i < len; i++) { if (i in this) { // if fn is not callable, it will throw fn.call(thisObject, this[i], i, this); } } }, every: function(fn, thisObject) { for (var i = 0, len = this.length; i < len; i++) { if ((i in this) && !fn.call(thisObject, this[i], i, this)) { return false; } } return true; }, map: function(fn, thisObject) { var ret = [], i = 0, l = this.length; for (; i < l; i++) { // if the subject of the index i is deleted, index i should not be contained in the result of array.map() if (i in this) { ret[i] = fn.call(thisObject, this[i], i, this); } } return ret; }, some: function(fn, thisObject) { for (var i = 0, l = this.length; i < l; i++) { if ((i in this) && fn.call(thisObject, this[i], i, this)) { return true; } } return false; }, reduce: function(fn) { if (typeof fn !== 'function') { throw new TYPE_ERROR(fn + ' is not an function'); } var self = this, len = self.length >>> 0, i = 0, ret; if (arguments.length > 1) { ret = arguments[1]; } else { do { if (i in self) { ret = self[i++]; break; } // if array contains no values, no initial value to return if (++i >= len) { throw new TYPE_ERROR('Reduce of empty array with on initial value'); } } while (true); } for (; i < len; i++) { if (i in self) { ret = fn.call(NULL, ret, self[i], i, self); } } return ret; }, reduceRight: function(fn) { if (typeof fn !== 'function') { throw new TYPE_ERROR(fn + ' is not an function'); } var self = this, len = self.length >>> 0, i = len - 1, ret; if (arguments.length > 1) { ret = arguments[1]; } else { do { if (i in self) { ret = self[i--]; break; } // if array contains no values, no initial value to return if (--i < 0) { throw new TYPE_ERROR('Reduce of empty array with on initial value'); } } while (true); } for (; i >= 0; i--) { if (i in self) { ret = fn.call(NULL, ret, self[i], i, self); } } return ret; } }); extend(Object, { // ~ https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/create ~ // create: function(o){ // if(o !== Object(o) && o !== NULL){ // throw new TYPE_ERROR('Object prototype may only be an Object or NULL'); // } // function F() {} // F.prototype = o; // return new F(); // }, // refs: // http://ejohn.org/blog/ecmascript-5-objects-and-properties/ // http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/keys // https://developer.mozilla.org/en/ECMAScript_DontEnum_attribute // http://msdn.microsoft.com/en-us/library/adebfyya(v=vs.94).aspx keys: (function() { var hasOwnProperty = Object.prototype.hasOwnProperty, has_dontEnumBug = !{ toString: '' }.propertyIsEnumerable('toString'), // In some old browsers, such as OLD IE, keys below might not be able to iterated with `for-in`, // even if each of them is one of current object's own properties NONT_ENUMS = [ 'toString', 'toLocaleString', 'valueOf', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'constructor' ], NONT_ENUMS_LENGTH = NONT_ENUMS.length; return function(o) { if (o !== Object(o)) { throw new TYPE_ERROR('Object.keys called on non-object'); } var ret = [], name; for (name in o) { if (hasOwnProperty.call(o, name)) { ret.push(name); } } if (has_dontEnumBug) { for (var i = 0; i < NONT_ENUMS_LENGTH; i++) { if (hasOwnProperty.call(o, NONT_ENUMS[i])) { ret.push(NONT_ENUMS[i]); } } } return ret; }; })() // for our current OOP pattern, we don't reply on Object based inheritance // so Neuron has not implemented the methods of Object such as Object.defineProperty, etc. }); implement(String, { trimLeft: function() { return this.replace(/^\s+/, ''); }, trimRight: function() { return this.replace(/\s+$/, ''); }, trim: function() { return this.trimLeft().trimRight(); } });