underscore-source 1.2.0 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/underscore-source/version.rb +1 -1
- data/vendor/assets/javascripts/underscore.js +107 -80
- metadata +1 -1
| @@ -1,4 +1,4 @@ | |
| 1 | 
            -
            //     Underscore.js 1.2. | 
| 1 | 
            +
            //     Underscore.js 1.2.1
         | 
| 2 2 | 
             
            //     (c) 2011 Jeremy Ashkenas, DocumentCloud Inc.
         | 
| 3 3 | 
             
            //     Underscore is freely distributable under the MIT license.
         | 
| 4 4 | 
             
            //     Portions of Underscore are inspired or borrowed from Prototype,
         | 
| @@ -48,19 +48,26 @@ | |
| 48 48 | 
             
              // Create a safe reference to the Underscore object for use below.
         | 
| 49 49 | 
             
              var _ = function(obj) { return new wrapper(obj); };
         | 
| 50 50 |  | 
| 51 | 
            -
              // Export the Underscore object for **CommonJS**, with | 
| 52 | 
            -
              // for the old `require()` API. If we're not in | 
| 53 | 
            -
              // global object.
         | 
| 54 | 
            -
              if (typeof  | 
| 55 | 
            -
                module.exports  | 
| 56 | 
            -
             | 
| 51 | 
            +
              // Export the Underscore object for **Node.js** and **"CommonJS"**, with
         | 
| 52 | 
            +
              // backwards-compatibility for the old `require()` API. If we're not in
         | 
| 53 | 
            +
              // CommonJS, add `_` to the global object.
         | 
| 54 | 
            +
              if (typeof exports !== 'undefined') {
         | 
| 55 | 
            +
                if (typeof module !== 'undefined' && module.exports) {
         | 
| 56 | 
            +
                  exports = module.exports = _;
         | 
| 57 | 
            +
                }
         | 
| 58 | 
            +
                exports._ = _;
         | 
| 59 | 
            +
              } else if (typeof define === 'function' && define.amd) {
         | 
| 60 | 
            +
                // Register as a named module with AMD.
         | 
| 61 | 
            +
                define('underscore', function() {
         | 
| 62 | 
            +
                  return _;
         | 
| 63 | 
            +
                });
         | 
| 57 64 | 
             
              } else {
         | 
| 58 65 | 
             
                // Exported as a string, for Closure Compiler "advanced" mode.
         | 
| 59 66 | 
             
                root['_'] = _;
         | 
| 60 67 | 
             
              }
         | 
| 61 68 |  | 
| 62 69 | 
             
              // Current version.
         | 
| 63 | 
            -
              _.VERSION = '1.2. | 
| 70 | 
            +
              _.VERSION = '1.2.1';
         | 
| 64 71 |  | 
| 65 72 | 
             
              // Collection Functions
         | 
| 66 73 | 
             
              // --------------------
         | 
| @@ -198,8 +205,8 @@ | |
| 198 205 | 
             
                var found = false;
         | 
| 199 206 | 
             
                if (obj == null) return found;
         | 
| 200 207 | 
             
                if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
         | 
| 201 | 
            -
                any(obj, function(value) {
         | 
| 202 | 
            -
                  if ( | 
| 208 | 
            +
                found = any(obj, function(value) {
         | 
| 209 | 
            +
                  if (value === target) return true;
         | 
| 203 210 | 
             
                });
         | 
| 204 211 | 
             
                return found;
         | 
| 205 212 | 
             
              };
         | 
| @@ -269,9 +276,11 @@ | |
| 269 276 | 
             
                }), 'value');
         | 
| 270 277 | 
             
              };
         | 
| 271 278 |  | 
| 272 | 
            -
              // Groups the object's values by a criterion  | 
| 273 | 
            -
               | 
| 279 | 
            +
              // Groups the object's values by a criterion. Pass either a string attribute
         | 
| 280 | 
            +
              // to group by, or a function that returns the criterion.
         | 
| 281 | 
            +
              _.groupBy = function(obj, val) {
         | 
| 274 282 | 
             
                var result = {};
         | 
| 283 | 
            +
                var iterator = _.isFunction(val) ? val : function(obj) { return obj[val]; };
         | 
| 275 284 | 
             
                each(obj, function(value, index) {
         | 
| 276 285 | 
             
                  var key = iterator(value, index);
         | 
| 277 286 | 
             
                  (result[key] || (result[key] = [])).push(value);
         | 
| @@ -343,9 +352,9 @@ | |
| 343 352 | 
             
              };
         | 
| 344 353 |  | 
| 345 354 | 
             
              // Return a completely flattened version of an array.
         | 
| 346 | 
            -
              _.flatten = function(array) {
         | 
| 355 | 
            +
              _.flatten = function(array, shallow) {
         | 
| 347 356 | 
             
                return _.reduce(array, function(memo, value) {
         | 
| 348 | 
            -
                  if (_.isArray(value)) return memo.concat(_.flatten(value));
         | 
| 357 | 
            +
                  if (_.isArray(value)) return memo.concat(shallow ? value : _.flatten(value));
         | 
| 349 358 | 
             
                  memo[memo.length] = value;
         | 
| 350 359 | 
             
                  return memo;
         | 
| 351 360 | 
             
                }, []);
         | 
| @@ -375,7 +384,7 @@ | |
| 375 384 | 
             
              // Produce an array that contains the union: each distinct element from all of
         | 
| 376 385 | 
             
              // the passed-in arrays.
         | 
| 377 386 | 
             
              _.union = function() {
         | 
| 378 | 
            -
                return _.uniq(_.flatten(arguments));
         | 
| 387 | 
            +
                return _.uniq(_.flatten(arguments, true));
         | 
| 379 388 | 
             
              };
         | 
| 380 389 |  | 
| 381 390 | 
             
              // Produce an array that contains every item shared between all the
         | 
| @@ -457,15 +466,25 @@ | |
| 457 466 | 
             
              // Function (ahem) Functions
         | 
| 458 467 | 
             
              // ------------------
         | 
| 459 468 |  | 
| 469 | 
            +
              // Reusable constructor function for prototype setting.
         | 
| 470 | 
            +
              var ctor = function(){};
         | 
| 471 | 
            +
             | 
| 460 472 | 
             
              // Create a function bound to a given object (assigning `this`, and arguments,
         | 
| 461 473 | 
             
              // optionally). Binding with arguments is also known as `curry`.
         | 
| 462 474 | 
             
              // Delegates to **ECMAScript 5**'s native `Function.bind` if available.
         | 
| 463 475 | 
             
              // We check for `func.bind` first, to fail fast when `func` is undefined.
         | 
| 464 | 
            -
              _.bind = function(func,  | 
| 476 | 
            +
              _.bind = function bind(func, context) {
         | 
| 477 | 
            +
                var bound, args;
         | 
| 465 478 | 
             
                if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
         | 
| 466 | 
            -
                 | 
| 467 | 
            -
                 | 
| 468 | 
            -
             | 
| 479 | 
            +
                if (!_.isFunction(func)) throw new TypeError;
         | 
| 480 | 
            +
                args = slice.call(arguments, 2);
         | 
| 481 | 
            +
                return bound = function() {
         | 
| 482 | 
            +
                  if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
         | 
| 483 | 
            +
                  ctor.prototype = func.prototype;
         | 
| 484 | 
            +
                  var self = new ctor;
         | 
| 485 | 
            +
                  var result = func.apply(self, args.concat(slice.call(arguments)));
         | 
| 486 | 
            +
                  if (Object(result) === result) return result;
         | 
| 487 | 
            +
                  return self;
         | 
| 469 488 | 
             
                };
         | 
| 470 489 | 
             
              };
         | 
| 471 490 |  | 
| @@ -501,31 +520,39 @@ | |
| 501 520 | 
             
                return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
         | 
| 502 521 | 
             
              };
         | 
| 503 522 |  | 
| 504 | 
            -
              //  | 
| 505 | 
            -
               | 
| 506 | 
            -
             | 
| 523 | 
            +
              // Returns a function, that, when invoked, will only be triggered at most once
         | 
| 524 | 
            +
              // during a given window of time.
         | 
| 525 | 
            +
              _.throttle = function(func, wait) {
         | 
| 526 | 
            +
                var timeout, context, args, throttling, finishThrottle;
         | 
| 527 | 
            +
                finishThrottle = _.debounce(function(){ throttling = false; }, wait);
         | 
| 507 528 | 
             
                return function() {
         | 
| 508 | 
            -
                   | 
| 529 | 
            +
                  context = this; args = arguments;
         | 
| 509 530 | 
             
                  var throttler = function() {
         | 
| 510 531 | 
             
                    timeout = null;
         | 
| 511 532 | 
             
                    func.apply(context, args);
         | 
| 533 | 
            +
                    finishThrottle();
         | 
| 512 534 | 
             
                  };
         | 
| 513 | 
            -
                  if ( | 
| 514 | 
            -
                  if ( | 
| 535 | 
            +
                  if (!timeout) timeout = setTimeout(throttler, wait);
         | 
| 536 | 
            +
                  if (!throttling) func.apply(context, args);
         | 
| 537 | 
            +
                  if (finishThrottle) finishThrottle();
         | 
| 538 | 
            +
                  throttling = true;
         | 
| 515 539 | 
             
                };
         | 
| 516 540 | 
             
              };
         | 
| 517 541 |  | 
| 518 | 
            -
              // Returns a function, that, when invoked, will only be triggered at most once
         | 
| 519 | 
            -
              // during a given window of time.
         | 
| 520 | 
            -
              _.throttle = function(func, wait) {
         | 
| 521 | 
            -
                return limit(func, wait, false);
         | 
| 522 | 
            -
              };
         | 
| 523 | 
            -
             | 
| 524 542 | 
             
              // Returns a function, that, as long as it continues to be invoked, will not
         | 
| 525 543 | 
             
              // be triggered. The function will be called after it stops being called for
         | 
| 526 544 | 
             
              // N milliseconds.
         | 
| 527 545 | 
             
              _.debounce = function(func, wait) {
         | 
| 528 | 
            -
                 | 
| 546 | 
            +
                var timeout;
         | 
| 547 | 
            +
                return function() {
         | 
| 548 | 
            +
                  var context = this, args = arguments;
         | 
| 549 | 
            +
                  var throttler = function() {
         | 
| 550 | 
            +
                    timeout = null;
         | 
| 551 | 
            +
                    func.apply(context, args);
         | 
| 552 | 
            +
                  };
         | 
| 553 | 
            +
                  clearTimeout(timeout);
         | 
| 554 | 
            +
                  timeout = setTimeout(throttler, wait);
         | 
| 555 | 
            +
                };
         | 
| 529 556 | 
             
              };
         | 
| 530 557 |  | 
| 531 558 | 
             
              // Returns a function that will be executed at most one time, no matter how
         | 
| @@ -618,6 +645,7 @@ | |
| 618 645 |  | 
| 619 646 | 
             
              // Create a (shallow-cloned) duplicate of an object.
         | 
| 620 647 | 
             
              _.clone = function(obj) {
         | 
| 648 | 
            +
                if (!_.isObject(obj)) return obj;
         | 
| 621 649 | 
             
                return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
         | 
| 622 650 | 
             
              };
         | 
| 623 651 |  | 
| @@ -635,7 +663,13 @@ | |
| 635 663 | 
             
                // See the Harmony `egal` proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal.
         | 
| 636 664 | 
             
                if (a === b) return a !== 0 || 1 / a == 1 / b;
         | 
| 637 665 | 
             
                // A strict comparison is necessary because `null == undefined`.
         | 
| 638 | 
            -
                if (a == null) return a === b;
         | 
| 666 | 
            +
                if ((a == null) || (b == null)) return a === b;
         | 
| 667 | 
            +
                // Unwrap any wrapped objects.
         | 
| 668 | 
            +
                if (a._chain) a = a._wrapped;
         | 
| 669 | 
            +
                if (b._chain) b = b._wrapped;
         | 
| 670 | 
            +
                // Invoke a custom `isEqual` method if one is provided.
         | 
| 671 | 
            +
                if (_.isFunction(a.isEqual)) return a.isEqual(b);
         | 
| 672 | 
            +
                if (_.isFunction(b.isEqual)) return b.isEqual(a);
         | 
| 639 673 | 
             
                // Compare object types.
         | 
| 640 674 | 
             
                var typeA = typeof a;
         | 
| 641 675 | 
             
                if (typeA != typeof b) return false;
         | 
| @@ -667,50 +701,36 @@ | |
| 667 701 | 
             
                }
         | 
| 668 702 | 
             
                // Ensure that both values are objects.
         | 
| 669 703 | 
             
                if (typeA != 'object') return false;
         | 
| 670 | 
            -
                //  | 
| 671 | 
            -
                if (a. | 
| 672 | 
            -
                 | 
| 673 | 
            -
                 | 
| 674 | 
            -
                 | 
| 675 | 
            -
                //  | 
| 676 | 
            -
                // adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
         | 
| 704 | 
            +
                // Arrays or Arraylikes with different lengths are not equal.
         | 
| 705 | 
            +
                if (a.length !== b.length) return false;
         | 
| 706 | 
            +
                // Objects with different constructors are not equal.
         | 
| 707 | 
            +
                if (a.constructor !== b.constructor) return false;
         | 
| 708 | 
            +
                // Assume equality for cyclic structures. The algorithm for detecting cyclic
         | 
| 709 | 
            +
                // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
         | 
| 677 710 | 
             
                var length = stack.length;
         | 
| 678 711 | 
             
                while (length--) {
         | 
| 679 | 
            -
                  // Linear search. Performance is inversely proportional to the number of | 
| 680 | 
            -
                  // structures.
         | 
| 712 | 
            +
                  // Linear search. Performance is inversely proportional to the number of
         | 
| 713 | 
            +
                  // unique nested structures.
         | 
| 681 714 | 
             
                  if (stack[length] == a) return true;
         | 
| 682 715 | 
             
                }
         | 
| 683 716 | 
             
                // Add the first object to the stack of traversed objects.
         | 
| 684 717 | 
             
                stack.push(a);
         | 
| 685 718 | 
             
                var size = 0, result = true;
         | 
| 686 | 
            -
                 | 
| 687 | 
            -
             | 
| 688 | 
            -
                   | 
| 689 | 
            -
             | 
| 690 | 
            -
             | 
| 691 | 
            -
                    // Deep compare  | 
| 692 | 
            -
                     | 
| 693 | 
            -
                      // Ensure commutative equality for sparse arrays.
         | 
| 694 | 
            -
                      if (!(result = size in a == size in b && eq(a[size], b[size], stack))) break;
         | 
| 695 | 
            -
                    }
         | 
| 696 | 
            -
                  }
         | 
| 697 | 
            -
                } else {
         | 
| 698 | 
            -
                  // Deep compare objects.
         | 
| 699 | 
            -
                  for (var key in a) {
         | 
| 700 | 
            -
                    if (hasOwnProperty.call(a, key)) {
         | 
| 701 | 
            -
                      // Count the expected number of properties.
         | 
| 702 | 
            -
                      size++;
         | 
| 703 | 
            -
                      // Deep compare each member.
         | 
| 704 | 
            -
                      if (!(result = hasOwnProperty.call(b, key) && eq(a[key], b[key], stack))) break;
         | 
| 705 | 
            -
                    }
         | 
| 719 | 
            +
                // Deep compare objects.
         | 
| 720 | 
            +
                for (var key in a) {
         | 
| 721 | 
            +
                  if (hasOwnProperty.call(a, key)) {
         | 
| 722 | 
            +
                    // Count the expected number of properties.
         | 
| 723 | 
            +
                    size++;
         | 
| 724 | 
            +
                    // Deep compare each member.
         | 
| 725 | 
            +
                    if (!(result = hasOwnProperty.call(b, key) && eq(a[key], b[key], stack))) break;
         | 
| 706 726 | 
             
                  }
         | 
| 707 | 
            -
             | 
| 708 | 
            -
             | 
| 709 | 
            -
             | 
| 710 | 
            -
             | 
| 711 | 
            -
                     | 
| 712 | 
            -
                    result = !size;
         | 
| 727 | 
            +
                }
         | 
| 728 | 
            +
                // Ensure that both objects contain the same number of properties.
         | 
| 729 | 
            +
                if (result) {
         | 
| 730 | 
            +
                  for (key in b) {
         | 
| 731 | 
            +
                    if (hasOwnProperty.call(b, key) && !size--) break;
         | 
| 713 732 | 
             
                  }
         | 
| 733 | 
            +
                  result = !size;
         | 
| 714 734 | 
             
                }
         | 
| 715 735 | 
             
                // Remove the first object from the stack of traversed objects.
         | 
| 716 736 | 
             
                stack.pop();
         | 
| @@ -722,7 +742,8 @@ | |
| 722 742 | 
             
                return eq(a, b, []);
         | 
| 723 743 | 
             
              };
         | 
| 724 744 |  | 
| 725 | 
            -
              // Is a given array or object empty?
         | 
| 745 | 
            +
              // Is a given array, string, or object empty?
         | 
| 746 | 
            +
              // An "empty" object has no enumerable own-properties.
         | 
| 726 747 | 
             
              _.isEmpty = function(obj) {
         | 
| 727 748 | 
             
                if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;
         | 
| 728 749 | 
             
                for (var key in obj) if (hasOwnProperty.call(obj, key)) return false;
         | 
| @@ -737,7 +758,7 @@ | |
| 737 758 | 
             
              // Is a given value an array?
         | 
| 738 759 | 
             
              // Delegates to ECMA5's native Array.isArray
         | 
| 739 760 | 
             
              _.isArray = nativeIsArray || function(obj) {
         | 
| 740 | 
            -
                return toString.call(obj)  | 
| 761 | 
            +
                return toString.call(obj) == '[object Array]';
         | 
| 741 762 | 
             
              };
         | 
| 742 763 |  | 
| 743 764 | 
             
              // Is a given variable an object?
         | 
| @@ -746,28 +767,34 @@ | |
| 746 767 | 
             
              };
         | 
| 747 768 |  | 
| 748 769 | 
             
              // Is a given variable an arguments object?
         | 
| 749 | 
            -
               | 
| 750 | 
            -
                 | 
| 751 | 
            -
             | 
| 770 | 
            +
              if (toString.call(arguments) == '[object Arguments]') {
         | 
| 771 | 
            +
                _.isArguments = function(obj) {
         | 
| 772 | 
            +
                  return toString.call(obj) == '[object Arguments]';
         | 
| 773 | 
            +
                };
         | 
| 774 | 
            +
              } else {
         | 
| 775 | 
            +
                _.isArguments = function(obj) {
         | 
| 776 | 
            +
                  return !!(obj && hasOwnProperty.call(obj, 'callee'));
         | 
| 777 | 
            +
                };
         | 
| 778 | 
            +
              }
         | 
| 752 779 |  | 
| 753 780 | 
             
              // Is a given value a function?
         | 
| 754 781 | 
             
              _.isFunction = function(obj) {
         | 
| 755 | 
            -
                return  | 
| 782 | 
            +
                return toString.call(obj) == '[object Function]';
         | 
| 756 783 | 
             
              };
         | 
| 757 784 |  | 
| 758 785 | 
             
              // Is a given value a string?
         | 
| 759 786 | 
             
              _.isString = function(obj) {
         | 
| 760 | 
            -
                return  | 
| 787 | 
            +
                return toString.call(obj) == '[object String]';
         | 
| 761 788 | 
             
              };
         | 
| 762 789 |  | 
| 763 790 | 
             
              // Is a given value a number?
         | 
| 764 791 | 
             
              _.isNumber = function(obj) {
         | 
| 765 | 
            -
                return  | 
| 792 | 
            +
                return toString.call(obj) == '[object Number]';
         | 
| 766 793 | 
             
              };
         | 
| 767 794 |  | 
| 768 | 
            -
              // Is the given value `NaN`? | 
| 769 | 
            -
              // that does not equal itself.
         | 
| 795 | 
            +
              // Is the given value `NaN`?
         | 
| 770 796 | 
             
              _.isNaN = function(obj) {
         | 
| 797 | 
            +
                // `NaN` is the only value for which `===` is not reflexive.
         | 
| 771 798 | 
             
                return obj !== obj;
         | 
| 772 799 | 
             
              };
         | 
| 773 800 |  | 
| @@ -778,12 +805,12 @@ | |
| 778 805 |  | 
| 779 806 | 
             
              // Is a given value a date?
         | 
| 780 807 | 
             
              _.isDate = function(obj) {
         | 
| 781 | 
            -
                return  | 
| 808 | 
            +
                return toString.call(obj) == '[object Date]';
         | 
| 782 809 | 
             
              };
         | 
| 783 810 |  | 
| 784 811 | 
             
              // Is the given value a regular expression?
         | 
| 785 812 | 
             
              _.isRegExp = function(obj) {
         | 
| 786 | 
            -
                return  | 
| 813 | 
            +
                return toString.call(obj) == '[object RegExp]';
         | 
| 787 814 | 
             
              };
         | 
| 788 815 |  | 
| 789 816 | 
             
              // Is a given value equal to null?
         |