From a86a20c9ecee2c04d265c88a21a7d1cdccab1029 Mon Sep 17 00:00:00 2001 From: Tim Wood Date: Thu, 16 Jun 2011 12:37:26 -0700 Subject: [PATCH] Fixing mixin with underscore --- test/date.js | 9 ++++ test/speed.js | 2 - test/test.html | 1 + test/vendor/underscore.js | 93 +++++++++++++++++++++++++++------------ underscore.date.js | 4 +- underscore.date.min.js | 2 +- 6 files changed, 78 insertions(+), 33 deletions(-) diff --git a/test/date.js b/test/date.js index a52cfea17..357205292 100755 --- a/test/date.js +++ b/test/date.js @@ -109,4 +109,13 @@ $(function() { equal(_date([2008, 0, 1]).isLeapYear(), true); equal(_date([2000, 0, 1]).isLeapYear(), true); }); + + test("underscore mixin", 6, function() { + ok(_.date([2010, 1, 12]).date instanceof Date, "[2010, 1, 12]"); + ok(_.date([2010, 1, 12, 1]).date instanceof Date, "[2010, 1, 12, 1]"); + ok(_.date().date instanceof Date, "undefined"); + ok(_.date("Aug 9, 1995").date instanceof Date, "Aug 9, 1995"); + ok(_.date("Mon, 25 Dec 1995 13:30:00 GMT").date instanceof Date, "Mon, 25 Dec 1995 13:30:00 GMT"); + deepEqual(_.date(new Date(2010, 1, 14, 15, 25, 50, 125)), _.date([2010, 1, 14, 15, 25, 50, 125]), "constructing with array === constructing with new Date()"); + }); }); \ No newline at end of file diff --git a/test/speed.js b/test/speed.js index 28adb3c51..665f6f726 100755 --- a/test/speed.js +++ b/test/speed.js @@ -1,7 +1,5 @@ (function() { - _ = _date; - var date1 = new Date(2010, 2, 6, 15, 25, 50, 125), date2 = new Date(1000); diff --git a/test/test.html b/test/test.html index 447f5fd85..459295050 100755 --- a/test/test.html +++ b/test/test.html @@ -4,6 +4,7 @@ Underscore.date test suite + diff --git a/test/vendor/underscore.js b/test/vendor/underscore.js index faa906005..97f09c3c7 100755 --- a/test/vendor/underscore.js +++ b/test/vendor/underscore.js @@ -1,4 +1,4 @@ -// Underscore.js 1.1.4 +// Underscore.js 1.1.6 // (c) 2011 Jeremy Ashkenas, DocumentCloud Inc. // Underscore is freely distributable under the MIT license. // Portions of Underscore are inspired or borrowed from Prototype, @@ -21,7 +21,7 @@ var breaker = {}; // Save bytes in the minified (but not gzipped) version: - var ArrayProto = Array.prototype, ObjProto = Object.prototype; + var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype; // Create quick reference variables for speed access to core prototypes. var slice = ArrayProto.slice, @@ -42,7 +42,8 @@ nativeIndexOf = ArrayProto.indexOf, nativeLastIndexOf = ArrayProto.lastIndexOf, nativeIsArray = Array.isArray, - nativeKeys = Object.keys; + nativeKeys = Object.keys, + nativeBind = FuncProto.bind; // Create a safe reference to the Underscore object for use below. var _ = function(obj) { return new wrapper(obj); }; @@ -58,7 +59,7 @@ } // Current version. - _.VERSION = '1.1.4'; + _.VERSION = '1.1.6'; // Collection Functions // -------------------- @@ -67,7 +68,6 @@ // Handles objects implementing `forEach`, arrays, and raw objects. // Delegates to **ECMAScript 5**'s native `forEach` if available. var each = _.each = _.forEach = function(obj, iterator, context) { - var value; if (obj == null) return; if (nativeForEach && obj.forEach === nativeForEach) { obj.forEach(iterator, context); @@ -168,7 +168,6 @@ // Delegates to **ECMAScript 5**'s native `every` if available. // Aliased as `all`. _.every = _.all = function(obj, iterator, context) { - iterator = iterator || _.identity; var result = true; if (obj == null) return result; if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context); @@ -182,7 +181,7 @@ // Delegates to **ECMAScript 5**'s native `some` if available. // Aliased as `any`. var any = _.some = _.any = function(obj, iterator, context) { - iterator = iterator || _.identity; + iterator || (iterator = _.identity); var result = false; if (obj == null) return result; if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context); @@ -208,7 +207,7 @@ _.invoke = function(obj, method) { var args = slice.call(arguments, 2); return _.map(obj, function(value) { - return (method ? value[method] : value).apply(value, args); + return (method.call ? method || value : value[method]).apply(value, args); }); }; @@ -255,7 +254,7 @@ // Use a comparator function to figure out at what index an object should // be inserted so as to maintain order. Uses binary search. _.sortedIndex = function(array, obj, iterator) { - iterator = iterator || _.identity; + iterator || (iterator = _.identity); var low = 0, high = array.length; while (low < high) { var mid = (low + high) >> 1; @@ -285,7 +284,7 @@ // values in the array. Aliased as `head`. The **guard** check allows it to work // with `_.map`. _.first = _.head = function(array, n, guard) { - return n && !guard ? slice.call(array, 0, n) : array[0]; + return (n != null) && !guard ? slice.call(array, 0, n) : array[0]; }; // Returns everything but the first entry of the array. Aliased as `tail`. @@ -293,7 +292,7 @@ // the rest of the values in the array from that index onward. The **guard** // check allows it to work with `_.map`. _.rest = _.tail = function(array, index, guard) { - return slice.call(array, _.isUndefined(index) || guard ? 1 : index); + return slice.call(array, (index == null) || guard ? 1 : index); }; // Get the last element of an array. @@ -360,12 +359,13 @@ // for **isSorted** to use binary search. _.indexOf = function(array, item, isSorted) { if (array == null) return -1; + var i, l; if (isSorted) { - var i = _.sortedIndex(array, item); + i = _.sortedIndex(array, item); return array[i] === item ? i : -1; } if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item); - for (var i = 0, l = array.length; i < l; i++) if (array[i] === item) return i; + for (i = 0, l = array.length; i < l; i++) if (array[i] === item) return i; return -1; }; @@ -383,18 +383,21 @@ // the native Python `range()` function. See // [the Python documentation](http://docs.python.org/library/functions.html#range). _.range = function(start, stop, step) { - var args = slice.call(arguments), - solo = args.length <= 1, - start = solo ? 0 : args[0], - stop = solo ? args[0] : args[1], - step = args[2] || 1, - len = Math.max(Math.ceil((stop - start) / step), 0), - idx = 0, - range = new Array(len); - while (idx < len) { + if (arguments.length <= 1) { + stop = start || 0; + start = 0; + } + step = arguments[2] || 1; + + var len = Math.max(Math.ceil((stop - start) / step), 0); + var idx = 0; + var range = new Array(len); + + while(idx < len) { range[idx++] = start; start += step; } + return range; }; @@ -403,10 +406,13 @@ // Create a function bound to a given object (assigning `this`, and arguments, // optionally). Binding with arguments is also known as `curry`. + // Delegates to **ECMAScript 5**'s native `Function.bind` if available. + // We check for `func.bind` first, to fail fast when `func` is undefined. _.bind = function(func, obj) { + if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1)); var args = slice.call(arguments, 2); return function() { - return func.apply(obj || {}, args.concat(slice.call(arguments))); + return func.apply(obj, args.concat(slice.call(arguments))); }; }; @@ -422,10 +428,10 @@ // Memoize an expensive function by storing its results. _.memoize = function(func, hasher) { var memo = {}; - hasher = hasher || _.identity; + hasher || (hasher = _.identity); return function() { var key = hasher.apply(this, arguments); - return key in memo ? memo[key] : (memo[key] = func.apply(this, arguments)); + return hasOwnProperty.call(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments)); }; }; @@ -469,6 +475,17 @@ return limit(func, wait, true); }; + // Returns a function that will be executed at most one time, no matter how + // often you call it. Useful for lazy initialization. + _.once = function(func) { + var ran = false, memo; + return function() { + if (ran) return memo; + ran = true; + return memo = func.apply(this, arguments); + }; + }; + // Returns the first function passed as an argument to the second, // allowing you to adjust arguments, run code before and after, and // conditionally execute the original function. @@ -492,13 +509,21 @@ }; }; + // Returns a function that will only be executed after being called N times. + _.after = function(times, func) { + return function() { + if (--times < 1) { return func.apply(this, arguments); } + }; + }; + + // Object Functions // ---------------- // Retrieve the names of an object's properties. // Delegates to **ECMAScript 5**'s native `Object.keys` _.keys = nativeKeys || function(obj) { - if (_.isArray(obj)) return _.range(0, obj.length); + if (obj !== Object(obj)) throw new TypeError('Invalid object'); var keys = []; for (var key in obj) if (hasOwnProperty.call(obj, key)) keys[keys.length] = key; return keys; @@ -518,7 +543,19 @@ // Extend a given object with all the properties in passed-in object(s). _.extend = function(obj) { each(slice.call(arguments, 1), function(source) { - for (var prop in source) obj[prop] = source[prop]; + for (var prop in source) { + if (source[prop] !== void 0) obj[prop] = source[prop]; + } + }); + return obj; + }; + + // Fill in a given object with default properties. + _.defaults = function(obj) { + each(slice.call(arguments, 1), function(source) { + for (var prop in source) { + if (obj[prop] == null) obj[prop] = source[prop]; + } }); return obj; }; @@ -767,4 +804,4 @@ return this._wrapped; }; -})(); +})(); \ No newline at end of file diff --git a/underscore.date.js b/underscore.date.js index 076a5c674..39e4981e1 100755 --- a/underscore.date.js +++ b/underscore.date.js @@ -386,8 +386,8 @@ module.exports = _date; // Integrate with Underscore.js } else { - if (this._ !== undefined) { - this._.mixin(_date); + if (this._ !== undefined && this._.mixin !== undefined) { + this._.mixin({date : _date}); } this._date = _date; } diff --git a/underscore.date.min.js b/underscore.date.min.js index bad1919de..ac6b0f172 100755 --- a/underscore.date.min.js +++ b/underscore.date.min.js @@ -1 +1 @@ -(function(a){function l(a){var b=Math.abs(a)/1e3,c=b/60,d=c/60,e=d/24,f=e/365;return b<45&&j("s",~~b)||b<90&&j("m")||c<45&&j("mm",~~c)||c<90&&j("h")||d<24&&j("hh",~~d)||d<48&&j("d")||e<25&&j("dd",~~e)||e<45&&j("M")||e<350&&j("MM",~~((e+15)/30))||f<2&&j("y")||j("yy",~~f)}function k(a,b){return i(a)-i(b)}function j(a,c){return b.relativeTime[a].replace(/%d/i,c||1)}function i(a){return isNaN(a)?(new h(a)).date.getTime():a}function h(b,c){b&&b.date instanceof Date?this.date=b.date:c?this.date=g(b,c):this.date=b===a?new Date:b instanceof Date?b:e(b)?f(b):new Date(b)}function g(a,b){function j(a,b){switch(a){case"M":case"MM":c[1]=~~b-1;break;case"D":case"DD":case"DDD":case"DDDD":c[2]=~~b;break;case"YY":b=~~b,c[0]=b+(b>70?1900:2e3);break;case"YYYY":c[0]=~~b;break;case"a":case"A":i=b.toLowerCase()==="pm";break;case"H":case"HH":case"h":case"hh":c[3]=~~b;break;case"m":case"mm":c[4]=~~b;break;case"s":case"ss":c[5]=~~b}}var c=[0],d=/[0-9a-zA-Z]+/g,e=[],g=[],h,i;a.replace(d,function(a){e.push(a)}),b.replace(d,function(a){g.push(a)});for(h=0;h11?"pm":"am";case"A":return i>11?"PM":"AM";case"H":return i;case"HH":return c(i,2);case"h":return i%12||12;case"hh":return c(i%12||12,2);case"m":return j;case"mm":return c(j,2);case"s":return k;case"ss":return c(k,2);case"z":return o("zz").replace(n,"");case"zz":d=l.indexOf("(");if(d>-1)return l.slice(d+1,l.indexOf(")"));return l.slice(l.indexOf(":")).replace(n,"");default:return a.replace("\\","")}}var d=this.date,e=d.getMonth(),f=d.getDate(),g=d.getFullYear(),h=d.getDay(),i=d.getHours(),j=d.getMinutes(),k=d.getSeconds(),l=d.toString(),m=/(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|dddd?|do?|w[o|w]?|YYYY|YY|a|A|hh?|HH?|mm?|ss?|zz?)/g,n=/[^A-Z]/g;return a.replace(m,o)},add:function(a){this.date=d(this.date,a,1);return this},subtract:function(a){this.date=d(this.date,a,-1);return this},from:function(a,c,d){var e=k(this.date,a),f=e<0?b.relativeTime.past:b.relativeTime.future;return d?e:c?l(e):f.replace(/%s/i,l(e))},fromNow:function(a,b){return this.from(new h,a,b)},isLeapYear:function(){var a=this.date.getFullYear();return a%4===0&&a%100!==0||a%400===0}},window===a&&module!==a?module.exports=b:(this._!==a&&this._.mixin(b),this._date=b)})() \ No newline at end of file +(function(a){function l(a){var b=Math.abs(a)/1e3,c=b/60,d=c/60,e=d/24,f=e/365;return b<45&&j("s",~~b)||b<90&&j("m")||c<45&&j("mm",~~c)||c<90&&j("h")||d<24&&j("hh",~~d)||d<48&&j("d")||e<25&&j("dd",~~e)||e<45&&j("M")||e<350&&j("MM",~~((e+15)/30))||f<2&&j("y")||j("yy",~~f)}function k(a,b){return i(a)-i(b)}function j(a,c){return b.relativeTime[a].replace(/%d/i,c||1)}function i(a){return isNaN(a)?(new h(a)).date.getTime():a}function h(b,c){b&&b.date instanceof Date?this.date=b.date:c?this.date=g(b,c):this.date=b===a?new Date:b instanceof Date?b:e(b)?f(b):new Date(b)}function g(a,b){function j(a,b){switch(a){case"M":case"MM":c[1]=~~b-1;break;case"D":case"DD":case"DDD":case"DDDD":c[2]=~~b;break;case"YY":b=~~b,c[0]=b+(b>70?1900:2e3);break;case"YYYY":c[0]=~~b;break;case"a":case"A":i=b.toLowerCase()==="pm";break;case"H":case"HH":case"h":case"hh":c[3]=~~b;break;case"m":case"mm":c[4]=~~b;break;case"s":case"ss":c[5]=~~b}}var c=[0],d=/[0-9a-zA-Z]+/g,e=[],g=[],h,i;a.replace(d,function(a){e.push(a)}),b.replace(d,function(a){g.push(a)});for(h=0;h11?"pm":"am";case"A":return i>11?"PM":"AM";case"H":return i;case"HH":return c(i,2);case"h":return i%12||12;case"hh":return c(i%12||12,2);case"m":return j;case"mm":return c(j,2);case"s":return k;case"ss":return c(k,2);case"z":return o("zz").replace(n,"");case"zz":d=l.indexOf("(");if(d>-1)return l.slice(d+1,l.indexOf(")"));return l.slice(l.indexOf(":")).replace(n,"");default:return a.replace("\\","")}}var d=this.date,e=d.getMonth(),f=d.getDate(),g=d.getFullYear(),h=d.getDay(),i=d.getHours(),j=d.getMinutes(),k=d.getSeconds(),l=d.toString(),m=/(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|dddd?|do?|w[o|w]?|YYYY|YY|a|A|hh?|HH?|mm?|ss?|zz?)/g,n=/[^A-Z]/g;return a.replace(m,o)},add:function(a){this.date=d(this.date,a,1);return this},subtract:function(a){this.date=d(this.date,a,-1);return this},from:function(a,c,d){var e=k(this.date,a),f=e<0?b.relativeTime.past:b.relativeTime.future;return d?e:c?l(e):f.replace(/%s/i,l(e))},fromNow:function(a,b){return this.from(new h,a,b)},isLeapYear:function(){var a=this.date.getFullYear();return a%4===0&&a%100!==0||a%400===0}},window===a&&module!==a?module.exports=b:(this._!==a&&this._.mixin!==a&&this._.mixin({date:b}),this._date=b)})() \ No newline at end of file -- 2.47.3