PageRenderTime 73ms CodeModel.GetById 33ms RepoModel.GetById 1ms app.codeStats 0ms

/community/server/src/main/resources/webadmin-html/js/lib/backbone.js

https://github.com/apcj/neo4j
JavaScript | 2007 lines | 1251 code | 262 blank | 494 comment | 417 complexity | 8a904b82c8c1dd028ef36f63d570d857 MD5 | raw file
Possible License(s): AGPL-1.0, MPL-2.0-no-copyleft-exception, GPL-2.0, JSON, LGPL-2.1, GPL-3.0, MIT, BSD-3-Clause, Apache-2.0, AGPL-3.0, CC-BY-SA-3.0

Large files files are truncated, but you can click here to view the full file

  1. // Underscore.js 1.1.7
  2. // (c) 2011 Jeremy Ashkenas, DocumentCloud Inc.
  3. // Underscore is freely distributable under the MIT license.
  4. // Portions of Underscore are inspired or borrowed from Prototype,
  5. // Oliver Steele's Functional, and John Resig's Micro-Templating.
  6. // For all details and documentation:
  7. // http://documentcloud.github.com/underscore
  8. (function() {
  9. // Baseline setup
  10. // --------------
  11. // Establish the root object, `window` in the browser, or `global` on the server.
  12. var root = this;
  13. // Save the previous value of the `_` variable.
  14. var previousUnderscore = root._;
  15. // Establish the object that gets returned to break out of a loop iteration.
  16. var breaker = {};
  17. // Save bytes in the minified (but not gzipped) version:
  18. var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
  19. // Create quick reference variables for speed access to core prototypes.
  20. var slice = ArrayProto.slice,
  21. unshift = ArrayProto.unshift,
  22. toString = ObjProto.toString,
  23. hasOwnProperty = ObjProto.hasOwnProperty;
  24. // All **ECMAScript 5** native function implementations that we hope to use
  25. // are declared here.
  26. var
  27. nativeForEach = ArrayProto.forEach,
  28. nativeMap = ArrayProto.map,
  29. nativeReduce = ArrayProto.reduce,
  30. nativeReduceRight = ArrayProto.reduceRight,
  31. nativeFilter = ArrayProto.filter,
  32. nativeEvery = ArrayProto.every,
  33. nativeSome = ArrayProto.some,
  34. nativeIndexOf = ArrayProto.indexOf,
  35. nativeLastIndexOf = ArrayProto.lastIndexOf,
  36. nativeIsArray = Array.isArray,
  37. nativeKeys = Object.keys,
  38. nativeBind = FuncProto.bind;
  39. // Create a safe reference to the Underscore object for use below.
  40. var _ = function(obj) { return new wrapper(obj); };
  41. // Export the Underscore object for **CommonJS**, with backwards-compatibility
  42. // for the old `require()` API. If we're not in CommonJS, add `_` to the
  43. // global object.
  44. if (typeof module !== 'undefined' && module.exports) {
  45. module.exports = _;
  46. _._ = _;
  47. } else {
  48. // Exported as a string, for Closure Compiler "advanced" mode.
  49. root['_'] = _;
  50. }
  51. // Current version.
  52. _.VERSION = '1.1.7';
  53. // Collection Functions
  54. // --------------------
  55. // The cornerstone, an `each` implementation, aka `forEach`.
  56. // Handles objects with the built-in `forEach`, arrays, and raw objects.
  57. // Delegates to **ECMAScript 5**'s native `forEach` if available.
  58. var each = _.each = _.forEach = function(obj, iterator, context) {
  59. if (obj == null) return;
  60. if (nativeForEach && obj.forEach === nativeForEach) {
  61. obj.forEach(iterator, context);
  62. } else if (obj.length === +obj.length) {
  63. for (var i = 0, l = obj.length; i < l; i++) {
  64. if (i in obj && iterator.call(context, obj[i], i, obj) === breaker) return;
  65. }
  66. } else {
  67. for (var key in obj) {
  68. if (hasOwnProperty.call(obj, key)) {
  69. if (iterator.call(context, obj[key], key, obj) === breaker) return;
  70. }
  71. }
  72. }
  73. };
  74. // Return the results of applying the iterator to each element.
  75. // Delegates to **ECMAScript 5**'s native `map` if available.
  76. _.map = function(obj, iterator, context) {
  77. var results = [];
  78. if (obj == null) return results;
  79. if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
  80. each(obj, function(value, index, list) {
  81. results[results.length] = iterator.call(context, value, index, list);
  82. });
  83. return results;
  84. };
  85. // **Reduce** builds up a single result from a list of values, aka `inject`,
  86. // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.
  87. _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
  88. var initial = memo !== void 0;
  89. if (obj == null) obj = [];
  90. if (nativeReduce && obj.reduce === nativeReduce) {
  91. if (context) iterator = _.bind(iterator, context);
  92. return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);
  93. }
  94. each(obj, function(value, index, list) {
  95. if (!initial) {
  96. memo = value;
  97. initial = true;
  98. } else {
  99. memo = iterator.call(context, memo, value, index, list);
  100. }
  101. });
  102. if (!initial) throw new TypeError("Reduce of empty array with no initial value");
  103. return memo;
  104. };
  105. // The right-associative version of reduce, also known as `foldr`.
  106. // Delegates to **ECMAScript 5**'s native `reduceRight` if available.
  107. _.reduceRight = _.foldr = function(obj, iterator, memo, context) {
  108. if (obj == null) obj = [];
  109. if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
  110. if (context) iterator = _.bind(iterator, context);
  111. return memo !== void 0 ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
  112. }
  113. var reversed = (_.isArray(obj) ? obj.slice() : _.toArray(obj)).reverse();
  114. return _.reduce(reversed, iterator, memo, context);
  115. };
  116. // Return the first value which passes a truth test. Aliased as `detect`.
  117. _.find = _.detect = function(obj, iterator, context) {
  118. var result;
  119. any(obj, function(value, index, list) {
  120. if (iterator.call(context, value, index, list)) {
  121. result = value;
  122. return true;
  123. }
  124. });
  125. return result;
  126. };
  127. // Return all the elements that pass a truth test.
  128. // Delegates to **ECMAScript 5**'s native `filter` if available.
  129. // Aliased as `select`.
  130. _.filter = _.select = function(obj, iterator, context) {
  131. var results = [];
  132. if (obj == null) return results;
  133. if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);
  134. each(obj, function(value, index, list) {
  135. if (iterator.call(context, value, index, list)) results[results.length] = value;
  136. });
  137. return results;
  138. };
  139. // Return all the elements for which a truth test fails.
  140. _.reject = function(obj, iterator, context) {
  141. var results = [];
  142. if (obj == null) return results;
  143. each(obj, function(value, index, list) {
  144. if (!iterator.call(context, value, index, list)) results[results.length] = value;
  145. });
  146. return results;
  147. };
  148. // Determine whether all of the elements match a truth test.
  149. // Delegates to **ECMAScript 5**'s native `every` if available.
  150. // Aliased as `all`.
  151. _.every = _.all = function(obj, iterator, context) {
  152. var result = true;
  153. if (obj == null) return result;
  154. if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);
  155. each(obj, function(value, index, list) {
  156. if (!(result = result && iterator.call(context, value, index, list))) return breaker;
  157. });
  158. return result;
  159. };
  160. // Determine if at least one element in the object matches a truth test.
  161. // Delegates to **ECMAScript 5**'s native `some` if available.
  162. // Aliased as `any`.
  163. var any = _.some = _.any = function(obj, iterator, context) {
  164. iterator = iterator || _.identity;
  165. var result = false;
  166. if (obj == null) return result;
  167. if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);
  168. each(obj, function(value, index, list) {
  169. if (result |= iterator.call(context, value, index, list)) return breaker;
  170. });
  171. return !!result;
  172. };
  173. // Determine if a given value is included in the array or object using `===`.
  174. // Aliased as `contains`.
  175. _.include = _.contains = function(obj, target) {
  176. var found = false;
  177. if (obj == null) return found;
  178. if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
  179. any(obj, function(value) {
  180. if (found = value === target) return true;
  181. });
  182. return found;
  183. };
  184. // Invoke a method (with arguments) on every item in a collection.
  185. _.invoke = function(obj, method) {
  186. var args = slice.call(arguments, 2);
  187. return _.map(obj, function(value) {
  188. return (method.call ? method || value : value[method]).apply(value, args);
  189. });
  190. };
  191. // Convenience version of a common use case of `map`: fetching a property.
  192. _.pluck = function(obj, key) {
  193. return _.map(obj, function(value){ return value[key]; });
  194. };
  195. // Return the maximum element or (element-based computation).
  196. _.max = function(obj, iterator, context) {
  197. if (!iterator && _.isArray(obj)) return Math.max.apply(Math, obj);
  198. var result = {computed : -Infinity};
  199. each(obj, function(value, index, list) {
  200. var computed = iterator ? iterator.call(context, value, index, list) : value;
  201. computed >= result.computed && (result = {value : value, computed : computed});
  202. });
  203. return result.value;
  204. };
  205. // Return the minimum element (or element-based computation).
  206. _.min = function(obj, iterator, context) {
  207. if (!iterator && _.isArray(obj)) return Math.min.apply(Math, obj);
  208. var result = {computed : Infinity};
  209. each(obj, function(value, index, list) {
  210. var computed = iterator ? iterator.call(context, value, index, list) : value;
  211. computed < result.computed && (result = {value : value, computed : computed});
  212. });
  213. return result.value;
  214. };
  215. // Sort the object's values by a criterion produced by an iterator.
  216. _.sortBy = function(obj, iterator, context) {
  217. return _.pluck(_.map(obj, function(value, index, list) {
  218. return {
  219. value : value,
  220. criteria : iterator.call(context, value, index, list)
  221. };
  222. }).sort(function(left, right) {
  223. var a = left.criteria, b = right.criteria;
  224. return a < b ? -1 : a > b ? 1 : 0;
  225. }), 'value');
  226. };
  227. // Groups the object's values by a criterion produced by an iterator
  228. _.groupBy = function(obj, iterator) {
  229. var result = {};
  230. each(obj, function(value, index) {
  231. var key = iterator(value, index);
  232. (result[key] || (result[key] = [])).push(value);
  233. });
  234. return result;
  235. };
  236. // Use a comparator function to figure out at what index an object should
  237. // be inserted so as to maintain order. Uses binary search.
  238. _.sortedIndex = function(array, obj, iterator) {
  239. iterator || (iterator = _.identity);
  240. var low = 0, high = array.length;
  241. while (low < high) {
  242. var mid = (low + high) >> 1;
  243. iterator(array[mid]) < iterator(obj) ? low = mid + 1 : high = mid;
  244. }
  245. return low;
  246. };
  247. // Safely convert anything iterable into a real, live array.
  248. _.toArray = function(iterable) {
  249. if (!iterable) return [];
  250. if (iterable.toArray) return iterable.toArray();
  251. if (_.isArray(iterable)) return slice.call(iterable);
  252. if (_.isArguments(iterable)) return slice.call(iterable);
  253. return _.values(iterable);
  254. };
  255. // Return the number of elements in an object.
  256. _.size = function(obj) {
  257. return _.toArray(obj).length;
  258. };
  259. // Array Functions
  260. // ---------------
  261. // Get the first element of an array. Passing **n** will return the first N
  262. // values in the array. Aliased as `head`. The **guard** check allows it to work
  263. // with `_.map`.
  264. _.first = _.head = function(array, n, guard) {
  265. return (n != null) && !guard ? slice.call(array, 0, n) : array[0];
  266. };
  267. // Returns everything but the first entry of the array. Aliased as `tail`.
  268. // Especially useful on the arguments object. Passing an **index** will return
  269. // the rest of the values in the array from that index onward. The **guard**
  270. // check allows it to work with `_.map`.
  271. _.rest = _.tail = function(array, index, guard) {
  272. return slice.call(array, (index == null) || guard ? 1 : index);
  273. };
  274. // Get the last element of an array.
  275. _.last = function(array) {
  276. return array[array.length - 1];
  277. };
  278. // Trim out all falsy values from an array.
  279. _.compact = function(array) {
  280. return _.filter(array, function(value){ return !!value; });
  281. };
  282. // Return a completely flattened version of an array.
  283. _.flatten = function(array) {
  284. return _.reduce(array, function(memo, value) {
  285. if (_.isArray(value)) return memo.concat(_.flatten(value));
  286. memo[memo.length] = value;
  287. return memo;
  288. }, []);
  289. };
  290. // Return a version of the array that does not contain the specified value(s).
  291. _.without = function(array) {
  292. return _.difference(array, slice.call(arguments, 1));
  293. };
  294. // Produce a duplicate-free version of the array. If the array has already
  295. // been sorted, you have the option of using a faster algorithm.
  296. // Aliased as `unique`.
  297. _.uniq = _.unique = function(array, isSorted, iterator) {
  298. var initial = iterator ? _.map(array, iterator) : array;
  299. var result = [];
  300. _.reduce(initial, function(memo, el, i) {
  301. if (0 == i || (isSorted === true ? _.last(memo) != el : !_.include(memo, el))) {
  302. memo[memo.length] = el;
  303. result[result.length] = array[i];
  304. }
  305. return memo;
  306. }, []);
  307. return result;
  308. };
  309. // Produce an array that contains the union: each distinct element from all of
  310. // the passed-in arrays.
  311. _.union = function() {
  312. return _.uniq(_.flatten(arguments));
  313. };
  314. // Produce an array that contains every item shared between all the
  315. // passed-in arrays. (Aliased as "intersect" for back-compat.)
  316. _.intersection = _.intersect = function(array) {
  317. var rest = slice.call(arguments, 1);
  318. return _.filter(_.uniq(array), function(item) {
  319. return _.every(rest, function(other) {
  320. return _.indexOf(other, item) >= 0;
  321. });
  322. });
  323. };
  324. // Take the difference between one array and another.
  325. // Only the elements present in just the first array will remain.
  326. _.difference = function(array, other) {
  327. return _.filter(array, function(value){ return !_.include(other, value); });
  328. };
  329. // Zip together multiple lists into a single array -- elements that share
  330. // an index go together.
  331. _.zip = function() {
  332. var args = slice.call(arguments);
  333. var length = _.max(_.pluck(args, 'length'));
  334. var results = new Array(length);
  335. for (var i = 0; i < length; i++) results[i] = _.pluck(args, "" + i);
  336. return results;
  337. };
  338. // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**),
  339. // we need this function. Return the position of the first occurrence of an
  340. // item in an array, or -1 if the item is not included in the array.
  341. // Delegates to **ECMAScript 5**'s native `indexOf` if available.
  342. // If the array is large and already in sort order, pass `true`
  343. // for **isSorted** to use binary search.
  344. _.indexOf = function(array, item, isSorted) {
  345. if (array == null) return -1;
  346. var i, l;
  347. if (isSorted) {
  348. i = _.sortedIndex(array, item);
  349. return array[i] === item ? i : -1;
  350. }
  351. if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item);
  352. for (i = 0, l = array.length; i < l; i++) if (array[i] === item) return i;
  353. return -1;
  354. };
  355. // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.
  356. _.lastIndexOf = function(array, item) {
  357. if (array == null) return -1;
  358. if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) return array.lastIndexOf(item);
  359. var i = array.length;
  360. while (i--) if (array[i] === item) return i;
  361. return -1;
  362. };
  363. // Generate an integer Array containing an arithmetic progression. A port of
  364. // the native Python `range()` function. See
  365. // [the Python documentation](http://docs.python.org/library/functions.html#range).
  366. _.range = function(start, stop, step) {
  367. if (arguments.length <= 1) {
  368. stop = start || 0;
  369. start = 0;
  370. }
  371. step = arguments[2] || 1;
  372. var len = Math.max(Math.ceil((stop - start) / step), 0);
  373. var idx = 0;
  374. var range = new Array(len);
  375. while(idx < len) {
  376. range[idx++] = start;
  377. start += step;
  378. }
  379. return range;
  380. };
  381. // Function (ahem) Functions
  382. // ------------------
  383. // Create a function bound to a given object (assigning `this`, and arguments,
  384. // optionally). Binding with arguments is also known as `curry`.
  385. // Delegates to **ECMAScript 5**'s native `Function.bind` if available.
  386. // We check for `func.bind` first, to fail fast when `func` is undefined.
  387. _.bind = function(func, obj) {
  388. if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
  389. var args = slice.call(arguments, 2);
  390. return function() {
  391. return func.apply(obj, args.concat(slice.call(arguments)));
  392. };
  393. };
  394. // Bind all of an object's methods to that object. Useful for ensuring that
  395. // all callbacks defined on an object belong to it.
  396. _.bindAll = function(obj) {
  397. var funcs = slice.call(arguments, 1);
  398. if (funcs.length == 0) funcs = _.functions(obj);
  399. each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
  400. return obj;
  401. };
  402. // Memoize an expensive function by storing its results.
  403. _.memoize = function(func, hasher) {
  404. var memo = {};
  405. hasher || (hasher = _.identity);
  406. return function() {
  407. var key = hasher.apply(this, arguments);
  408. return hasOwnProperty.call(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));
  409. };
  410. };
  411. // Delays a function for the given number of milliseconds, and then calls
  412. // it with the arguments supplied.
  413. _.delay = function(func, wait) {
  414. var args = slice.call(arguments, 2);
  415. return setTimeout(function(){ return func.apply(func, args); }, wait);
  416. };
  417. // Defers a function, scheduling it to run after the current call stack has
  418. // cleared.
  419. _.defer = function(func) {
  420. return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
  421. };
  422. // Internal function used to implement `_.throttle` and `_.debounce`.
  423. var limit = function(func, wait, debounce) {
  424. var timeout;
  425. return function() {
  426. var context = this, args = arguments;
  427. var throttler = function() {
  428. timeout = null;
  429. func.apply(context, args);
  430. };
  431. if (debounce) clearTimeout(timeout);
  432. if (debounce || !timeout) timeout = setTimeout(throttler, wait);
  433. };
  434. };
  435. // Returns a function, that, when invoked, will only be triggered at most once
  436. // during a given window of time.
  437. _.throttle = function(func, wait) {
  438. return limit(func, wait, false);
  439. };
  440. // Returns a function, that, as long as it continues to be invoked, will not
  441. // be triggered. The function will be called after it stops being called for
  442. // N milliseconds.
  443. _.debounce = function(func, wait) {
  444. return limit(func, wait, true);
  445. };
  446. // Returns a function that will be executed at most one time, no matter how
  447. // often you call it. Useful for lazy initialization.
  448. _.once = function(func) {
  449. var ran = false, memo;
  450. return function() {
  451. if (ran) return memo;
  452. ran = true;
  453. return memo = func.apply(this, arguments);
  454. };
  455. };
  456. // Returns the first function passed as an argument to the second,
  457. // allowing you to adjust arguments, run code before and after, and
  458. // conditionally execute the original function.
  459. _.wrap = function(func, wrapper) {
  460. return function() {
  461. var args = [func].concat(slice.call(arguments));
  462. return wrapper.apply(this, args);
  463. };
  464. };
  465. // Returns a function that is the composition of a list of functions, each
  466. // consuming the return value of the function that follows.
  467. _.compose = function() {
  468. var funcs = slice.call(arguments);
  469. return function() {
  470. var args = slice.call(arguments);
  471. for (var i = funcs.length - 1; i >= 0; i--) {
  472. args = [funcs[i].apply(this, args)];
  473. }
  474. return args[0];
  475. };
  476. };
  477. // Returns a function that will only be executed after being called N times.
  478. _.after = function(times, func) {
  479. return function() {
  480. if (--times < 1) { return func.apply(this, arguments); }
  481. };
  482. };
  483. // Object Functions
  484. // ----------------
  485. // Retrieve the names of an object's properties.
  486. // Delegates to **ECMAScript 5**'s native `Object.keys`
  487. _.keys = nativeKeys || function(obj) {
  488. if (obj !== Object(obj)) throw new TypeError('Invalid object');
  489. var keys = [];
  490. for (var key in obj) if (hasOwnProperty.call(obj, key)) keys[keys.length] = key;
  491. return keys;
  492. };
  493. // Retrieve the values of an object's properties.
  494. _.values = function(obj) {
  495. return _.map(obj, _.identity);
  496. };
  497. // Return a sorted list of the function names available on the object.
  498. // Aliased as `methods`
  499. _.functions = _.methods = function(obj) {
  500. var names = [];
  501. for (var key in obj) {
  502. if (_.isFunction(obj[key])) names.push(key);
  503. }
  504. return names.sort();
  505. };
  506. // Extend a given object with all the properties in passed-in object(s).
  507. _.extend = function(obj) {
  508. each(slice.call(arguments, 1), function(source) {
  509. for (var prop in source) {
  510. if (source[prop] !== void 0) obj[prop] = source[prop];
  511. }
  512. });
  513. return obj;
  514. };
  515. // Fill in a given object with default properties.
  516. _.defaults = function(obj) {
  517. each(slice.call(arguments, 1), function(source) {
  518. for (var prop in source) {
  519. if (obj[prop] == null) obj[prop] = source[prop];
  520. }
  521. });
  522. return obj;
  523. };
  524. // Create a (shallow-cloned) duplicate of an object.
  525. _.clone = function(obj) {
  526. return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
  527. };
  528. // Invokes interceptor with the obj, and then returns obj.
  529. // The primary purpose of this method is to "tap into" a method chain, in
  530. // order to perform operations on intermediate results within the chain.
  531. _.tap = function(obj, interceptor) {
  532. interceptor(obj);
  533. return obj;
  534. };
  535. // Perform a deep comparison to check if two objects are equal.
  536. _.isEqual = function(a, b) {
  537. // Check object identity.
  538. if (a === b) return true;
  539. // Different types?
  540. var atype = typeof(a), btype = typeof(b);
  541. if (atype != btype) return false;
  542. // Basic equality test (watch out for coercions).
  543. if (a == b) return true;
  544. // One is falsy and the other truthy.
  545. if ((!a && b) || (a && !b)) return false;
  546. // Unwrap any wrapped objects.
  547. if (a._chain) a = a._wrapped;
  548. if (b._chain) b = b._wrapped;
  549. // One of them implements an isEqual()?
  550. if (a.isEqual) return a.isEqual(b);
  551. if (b.isEqual) return b.isEqual(a);
  552. // Check dates' integer values.
  553. if (_.isDate(a) && _.isDate(b)) return a.getTime() === b.getTime();
  554. // Both are NaN?
  555. if (_.isNaN(a) && _.isNaN(b)) return false;
  556. // Compare regular expressions.
  557. if (_.isRegExp(a) && _.isRegExp(b))
  558. return a.source === b.source &&
  559. a.global === b.global &&
  560. a.ignoreCase === b.ignoreCase &&
  561. a.multiline === b.multiline;
  562. // If a is not an object by this point, we can't handle it.
  563. if (atype !== 'object') return false;
  564. // Check for different array lengths before comparing contents.
  565. if (a.length && (a.length !== b.length)) return false;
  566. // Nothing else worked, deep compare the contents.
  567. var aKeys = _.keys(a), bKeys = _.keys(b);
  568. // Different object sizes?
  569. if (aKeys.length != bKeys.length) return false;
  570. // Recursive comparison of contents.
  571. for (var key in a) if (!(key in b) || !_.isEqual(a[key], b[key])) return false;
  572. return true;
  573. };
  574. // Is a given array or object empty?
  575. _.isEmpty = function(obj) {
  576. if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;
  577. for (var key in obj) if (hasOwnProperty.call(obj, key)) return false;
  578. return true;
  579. };
  580. // Is a given value a DOM element?
  581. _.isElement = function(obj) {
  582. return !!(obj && obj.nodeType == 1);
  583. };
  584. // Is a given value an array?
  585. // Delegates to ECMA5's native Array.isArray
  586. _.isArray = nativeIsArray || function(obj) {
  587. return toString.call(obj) === '[object Array]';
  588. };
  589. // Is a given variable an object?
  590. _.isObject = function(obj) {
  591. return obj === Object(obj);
  592. };
  593. // Is a given variable an arguments object?
  594. _.isArguments = function(obj) {
  595. return !!(obj && hasOwnProperty.call(obj, 'callee'));
  596. };
  597. // Is a given value a function?
  598. _.isFunction = function(obj) {
  599. return !!(obj && obj.constructor && obj.call && obj.apply);
  600. };
  601. // Is a given value a string?
  602. _.isString = function(obj) {
  603. return !!(obj === '' || (obj && obj.charCodeAt && obj.substr));
  604. };
  605. // Is a given value a number?
  606. _.isNumber = function(obj) {
  607. return !!(obj === 0 || (obj && obj.toExponential && obj.toFixed));
  608. };
  609. // Is the given value `NaN`? `NaN` happens to be the only value in JavaScript
  610. // that does not equal itself.
  611. _.isNaN = function(obj) {
  612. return obj !== obj;
  613. };
  614. // Is a given value a boolean?
  615. _.isBoolean = function(obj) {
  616. return obj === true || obj === false;
  617. };
  618. // Is a given value a date?
  619. _.isDate = function(obj) {
  620. return !!(obj && obj.getTimezoneOffset && obj.setUTCFullYear);
  621. };
  622. // Is the given value a regular expression?
  623. _.isRegExp = function(obj) {
  624. return !!(obj && obj.test && obj.exec && (obj.ignoreCase || obj.ignoreCase === false));
  625. };
  626. // Is a given value equal to null?
  627. _.isNull = function(obj) {
  628. return obj === null;
  629. };
  630. // Is a given variable undefined?
  631. _.isUndefined = function(obj) {
  632. return obj === void 0;
  633. };
  634. // Utility Functions
  635. // -----------------
  636. // Run Underscore.js in *noConflict* mode, returning the `_` variable to its
  637. // previous owner. Returns a reference to the Underscore object.
  638. _.noConflict = function() {
  639. root._ = previousUnderscore;
  640. return this;
  641. };
  642. // Keep the identity function around for default iterators.
  643. _.identity = function(value) {
  644. return value;
  645. };
  646. // Run a function **n** times.
  647. _.times = function (n, iterator, context) {
  648. for (var i = 0; i < n; i++) iterator.call(context, i);
  649. };
  650. // Add your own custom functions to the Underscore object, ensuring that
  651. // they're correctly added to the OOP wrapper as well.
  652. _.mixin = function(obj) {
  653. each(_.functions(obj), function(name){
  654. addToWrapper(name, _[name] = obj[name]);
  655. });
  656. };
  657. // Generate a unique integer id (unique within the entire client session).
  658. // Useful for temporary DOM ids.
  659. var idCounter = 0;
  660. _.uniqueId = function(prefix) {
  661. var id = idCounter++;
  662. return prefix ? prefix + id : id;
  663. };
  664. // By default, Underscore uses ERB-style template delimiters, change the
  665. // following template settings to use alternative delimiters.
  666. _.templateSettings = {
  667. evaluate : /<%([\s\S]+?)%>/g,
  668. interpolate : /<%=([\s\S]+?)%>/g
  669. };
  670. // JavaScript micro-templating, similar to John Resig's implementation.
  671. // Underscore templating handles arbitrary delimiters, preserves whitespace,
  672. // and correctly escapes quotes within interpolated code.
  673. _.template = function(str, data) {
  674. var c = _.templateSettings;
  675. var tmpl = 'var __p=[],print=function(){__p.push.apply(__p,arguments);};' +
  676. 'with(obj||{}){__p.push(\'' +
  677. str.replace(/\\/g, '\\\\')
  678. .replace(/'/g, "\\'")
  679. .replace(c.interpolate, function(match, code) {
  680. return "'," + code.replace(/\\'/g, "'") + ",'";
  681. })
  682. .replace(c.evaluate || null, function(match, code) {
  683. return "');" + code.replace(/\\'/g, "'")
  684. .replace(/[\r\n\t]/g, ' ') + "__p.push('";
  685. })
  686. .replace(/\r/g, '\\r')
  687. .replace(/\n/g, '\\n')
  688. .replace(/\t/g, '\\t')
  689. + "');}return __p.join('');";
  690. var func = new Function('obj', tmpl);
  691. return data ? func(data) : func;
  692. };
  693. // The OOP Wrapper
  694. // ---------------
  695. // If Underscore is called as a function, it returns a wrapped object that
  696. // can be used OO-style. This wrapper holds altered versions of all the
  697. // underscore functions. Wrapped objects may be chained.
  698. var wrapper = function(obj) { this._wrapped = obj; };
  699. // Expose `wrapper.prototype` as `_.prototype`
  700. _.prototype = wrapper.prototype;
  701. // Helper function to continue chaining intermediate results.
  702. var result = function(obj, chain) {
  703. return chain ? _(obj).chain() : obj;
  704. };
  705. // A method to easily add functions to the OOP wrapper.
  706. var addToWrapper = function(name, func) {
  707. wrapper.prototype[name] = function() {
  708. var args = slice.call(arguments);
  709. unshift.call(args, this._wrapped);
  710. return result(func.apply(_, args), this._chain);
  711. };
  712. };
  713. // Add all of the Underscore functions to the wrapper object.
  714. _.mixin(_);
  715. // Add all mutator Array functions to the wrapper.
  716. each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
  717. var method = ArrayProto[name];
  718. wrapper.prototype[name] = function() {
  719. method.apply(this._wrapped, arguments);
  720. return result(this._wrapped, this._chain);
  721. };
  722. });
  723. // Add all accessor Array functions to the wrapper.
  724. each(['concat', 'join', 'slice'], function(name) {
  725. var method = ArrayProto[name];
  726. wrapper.prototype[name] = function() {
  727. return result(method.apply(this._wrapped, arguments), this._chain);
  728. };
  729. });
  730. // Start chaining a wrapped Underscore object.
  731. wrapper.prototype.chain = function() {
  732. this._chain = true;
  733. return this;
  734. };
  735. // Extracts the result from a wrapped and chained object.
  736. wrapper.prototype.value = function() {
  737. return this._wrapped;
  738. };
  739. })();
  740. // Backbone.js 0.5.3
  741. // (c) 2010 Jeremy Ashkenas, DocumentCloud Inc.
  742. // Backbone may be freely distributed under the MIT license.
  743. // For all details and documentation:
  744. // http://documentcloud.github.com/backbone
  745. (function(){
  746. // Initial Setup
  747. // -------------
  748. // Save a reference to the global object.
  749. var root = this;
  750. // Save the previous value of the `Backbone` variable.
  751. var previousBackbone = root.Backbone;
  752. // The top-level namespace. All public Backbone classes and modules will
  753. // be attached to this. Exported for both CommonJS and the browser.
  754. var Backbone;
  755. if (typeof exports !== 'undefined') {
  756. Backbone = exports;
  757. } else {
  758. Backbone = root.Backbone = {};
  759. }
  760. // Current version of the library. Keep in sync with `package.json`.
  761. Backbone.VERSION = '0.5.3';
  762. // Require Underscore, if we're on the server, and it's not already present.
  763. var _ = root._;
  764. if (!_ && (typeof require !== 'undefined')) _ = require('underscore')._;
  765. // For Backbone's purposes, jQuery or Zepto owns the `$` variable.
  766. // Commented out, because jQuery is sometimes not defined at this point
  767. //var $ = root.jQuery || root.Zepto;
  768. // Runs Backbone.js in *noConflict* mode, returning the `Backbone` variable
  769. // to its previous owner. Returns a reference to this Backbone object.
  770. Backbone.noConflict = function() {
  771. root.Backbone = previousBackbone;
  772. return this;
  773. };
  774. // Turn on `emulateHTTP` to support legacy HTTP servers. Setting this option will
  775. // fake `"PUT"` and `"DELETE"` requests via the `_method` parameter and set a
  776. // `X-Http-Method-Override` header.
  777. Backbone.emulateHTTP = false;
  778. // Turn on `emulateJSON` to support legacy servers that can't deal with direct
  779. // `application/json` requests ... will encode the body as
  780. // `application/x-www-form-urlencoded` instead and will send the model in a
  781. // form param named `model`.
  782. Backbone.emulateJSON = false;
  783. // Backbone.Events
  784. // -----------------
  785. // A module that can be mixed in to *any object* in order to provide it with
  786. // custom events. You may `bind` or `unbind` a callback function to an event;
  787. // `trigger`-ing an event fires all callbacks in succession.
  788. //
  789. // var object = {};
  790. // _.extend(object, Backbone.Events);
  791. // object.bind('expand', function(){ alert('expanded'); });
  792. // object.trigger('expand');
  793. //
  794. Backbone.Events = {
  795. // Bind an event, specified by a string name, `ev`, to a `callback` function.
  796. // Passing `"all"` will bind the callback to all events fired.
  797. bind : function(ev, callback, context) {
  798. var calls = this._callbacks || (this._callbacks = {});
  799. var list = calls[ev] || (calls[ev] = []);
  800. list.push([callback, context]);
  801. return this;
  802. },
  803. // Remove one or many callbacks. If `callback` is null, removes all
  804. // callbacks for the event. If `ev` is null, removes all bound callbacks
  805. // for all events.
  806. unbind : function(ev, callback) {
  807. var calls;
  808. if (!ev) {
  809. this._callbacks = {};
  810. } else if (calls = this._callbacks) {
  811. if (!callback) {
  812. calls[ev] = [];
  813. } else {
  814. var list = calls[ev];
  815. if (!list) return this;
  816. for (var i = 0, l = list.length; i < l; i++) {
  817. if (list[i] && callback === list[i][0]) {
  818. list[i] = null;
  819. break;
  820. }
  821. }
  822. }
  823. }
  824. return this;
  825. },
  826. // Trigger an event, firing all bound callbacks. Callbacks are passed the
  827. // same arguments as `trigger` is, apart from the event name.
  828. // Listening for `"all"` passes the true event name as the first argument.
  829. trigger : function(eventName) {
  830. var list, calls, ev, callback, args;
  831. var both = 2;
  832. if (!(calls = this._callbacks)) return this;
  833. while (both--) {
  834. ev = both ? eventName : 'all';
  835. if (list = calls[ev]) {
  836. for (var i = 0, l = list.length; i < l; i++) {
  837. if (!(callback = list[i])) {
  838. list.splice(i, 1); i--; l--;
  839. } else {
  840. args = both ? Array.prototype.slice.call(arguments, 1) : arguments;
  841. callback[0].apply(callback[1] || this, args);
  842. }
  843. }
  844. }
  845. }
  846. return this;
  847. }
  848. };
  849. // Backbone.Model
  850. // --------------
  851. // Create a new model, with defined attributes. A client id (`cid`)
  852. // is automatically generated and assigned for you.
  853. Backbone.Model = function(attributes, options) {
  854. var defaults;
  855. attributes || (attributes = {});
  856. if (defaults = this.defaults) {
  857. if (_.isFunction(defaults)) defaults = defaults.call(this);
  858. attributes = _.extend({}, defaults, attributes);
  859. }
  860. this.attributes = {};
  861. this._escapedAttributes = {};
  862. this.cid = _.uniqueId('c');
  863. this.set(attributes, {silent : true});
  864. this._changed = false;
  865. this._previousAttributes = _.clone(this.attributes);
  866. if (options && options.collection) this.collection = options.collection;
  867. this.initialize(attributes, options);
  868. };
  869. // Attach all inheritable methods to the Model prototype.
  870. _.extend(Backbone.Model.prototype, Backbone.Events, {
  871. // A snapshot of the model's previous attributes, taken immediately
  872. // after the last `"change"` event was fired.
  873. _previousAttributes : null,
  874. // Has the item been changed since the last `"change"` event?
  875. _changed : false,
  876. // The default name for the JSON `id` attribute is `"id"`. MongoDB and
  877. // CouchDB users may want to set this to `"_id"`.
  878. idAttribute : 'id',
  879. // Initialize is an empty function by default. Override it with your own
  880. // initialization logic.
  881. initialize : function(){},
  882. // Return a copy of the model's `attributes` object.
  883. toJSON : function() {
  884. return _.clone(this.attributes);
  885. },
  886. // Get the value of an attribute.
  887. get : function(attr) {
  888. return this.attributes[attr];
  889. },
  890. // Get the HTML-escaped value of an attribute.
  891. escape : function(attr) {
  892. var html;
  893. if (html = this._escapedAttributes[attr]) return html;
  894. var val = this.attributes[attr];
  895. return this._escapedAttributes[attr] = escapeHTML(val == null ? '' : '' + val);
  896. },
  897. // Returns `true` if the attribute contains a value that is not null
  898. // or undefined.
  899. has : function(attr) {
  900. return this.attributes[attr] != null;
  901. },
  902. // Set a hash of model attributes on the object, firing `"change"` unless you
  903. // choose to silence it.
  904. set : function(attrs, options) {
  905. // Extract attributes and options.
  906. options || (options = {});
  907. if (!attrs) return this;
  908. if (attrs.attributes) attrs = attrs.attributes;
  909. var now = this.attributes, escaped = this._escapedAttributes;
  910. // Run validation.
  911. if (!options.silent && this.validate && !this._performValidation(attrs, options)) return false;
  912. // Check for changes of `id`.
  913. if (this.idAttribute in attrs) this.id = attrs[this.idAttribute];
  914. // We're about to start triggering change events.
  915. var alreadyChanging = this._changing;
  916. this._changing = true;
  917. // Update attributes.
  918. for (var attr in attrs) {
  919. var val = attrs[attr];
  920. if (!_.isEqual(now[attr], val)) {
  921. now[attr] = val;
  922. delete escaped[attr];
  923. this._changed = true;
  924. if (!options.silent) this.trigger('change:' + attr, this, val, options);
  925. }
  926. }
  927. // Fire the `"change"` event, if the model has been changed.
  928. if (!alreadyChanging && !options.silent && this._changed) this.change(options);
  929. this._changing = false;
  930. return this;
  931. },
  932. // Remove an attribute from the model, firing `"change"` unless you choose
  933. // to silence it. `unset` is a noop if the attribute doesn't exist.
  934. unset : function(attr, options) {
  935. if (!(attr in this.attributes)) return this;
  936. options || (options = {});
  937. var value = this.attributes[attr];
  938. // Run validation.
  939. var validObj = {};
  940. validObj[attr] = void 0;
  941. if (!options.silent && this.validate && !this._performValidation(validObj, options)) return false;
  942. // Remove the attribute.
  943. delete this.attributes[attr];
  944. delete this._escapedAttributes[attr];
  945. if (attr == this.idAttribute) delete this.id;
  946. this._changed = true;
  947. if (!options.silent) {
  948. this.trigger('change:' + attr, this, void 0, options);
  949. this.change(options);
  950. }
  951. return this;
  952. },
  953. // Clear all attributes on the model, firing `"change"` unless you choose
  954. // to silence it.
  955. clear : function(options) {
  956. options || (options = {});
  957. var attr;
  958. var old = this.attributes;
  959. // Run validation.
  960. var validObj = {};
  961. for (attr in old) validObj[attr] = void 0;
  962. if (!options.silent && this.validate && !this._performValidation(validObj, options)) return false;
  963. this.attributes = {};
  964. this._escapedAttributes = {};
  965. this._changed = true;
  966. if (!options.silent) {
  967. for (attr in old) {
  968. this.trigger('change:' + attr, this, void 0, options);
  969. }
  970. this.change(options);
  971. }
  972. return this;
  973. },
  974. // Fetch the model from the server. If the server's representation of the
  975. // model differs from its current attributes, they will be overriden,
  976. // triggering a `"change"` event.
  977. fetch : function(options) {
  978. options || (options = {});
  979. var model = this;
  980. var success = options.success;
  981. options.success = function(resp, status, xhr) {
  982. if (!model.set(model.parse(resp, xhr), options)) return false;
  983. if (success) success(model, resp);
  984. };
  985. options.error = wrapError(options.error, model, options);
  986. return (this.sync || Backbone.sync).call(this, 'read', this, options);
  987. },
  988. // Set a hash of model attributes, and sync the model to the server.
  989. // If the server returns an attributes hash that differs, the model's
  990. // state will be `set` again.
  991. save : function(attrs, options) {
  992. options || (options = {});
  993. if (attrs && !this.set(attrs, options)) return false;
  994. var model = this;
  995. var success = options.success;
  996. options.success = function(resp, status, xhr) {
  997. if (!model.set(model.parse(resp, xhr), options)) return false;
  998. if (success) success(model, resp, xhr);
  999. };
  1000. options.error = wrapError(options.error, model, options);
  1001. var method = this.isNew() ? 'create' : 'update';
  1002. return (this.sync || Backbone.sync).call(this, method, this, options);
  1003. },
  1004. // Destroy this model on the server if it was already persisted. Upon success, the model is removed
  1005. // from its collection, if it has one.
  1006. destroy : function(options) {
  1007. options || (options = {});
  1008. if (this.isNew()) return this.trigger('destroy', this, this.collection, options);
  1009. var model = this;
  1010. var success = options.success;
  1011. options.success = function(resp) {
  1012. model.trigger('destroy', model, model.collection, options);
  1013. if (success) success(model, resp);
  1014. };
  1015. options.error = wrapError(options.error, model, options);
  1016. return (this.sync || Backbone.sync).call(this, 'delete', this, options);
  1017. },
  1018. // Default URL for the model's representation on the server -- if you're
  1019. // using Backbone's restful methods, override this to change the endpoint
  1020. // that will be called.
  1021. url : function() {
  1022. var base = getUrl(this.collection) || this.urlRoot || urlError();
  1023. if (this.isNew()) return base;
  1024. return base + (base.charAt(base.length - 1) == '/' ? '' : '/') + encodeURIComponent(this.id);
  1025. },
  1026. // **parse** converts a response into the hash of attributes to be `set` on
  1027. // the model. The default implementation is just to pass the response along.
  1028. parse : function(resp, xhr) {
  1029. return resp;
  1030. },
  1031. // Create a new model with identical attributes to this one.
  1032. clone : function() {
  1033. return new this.constructor(this);
  1034. },
  1035. // A model is new if it has never been saved to the server, and lacks an id.
  1036. isNew : function() {
  1037. return this.id == null;
  1038. },
  1039. // Call this method to manually fire a `change` event for this model.
  1040. // Calling this will cause all objects observing the model to update.
  1041. change : function(options) {
  1042. this.trigger('change', this, options);
  1043. this._previousAttributes = _.clone(this.attributes);
  1044. this._changed = false;
  1045. },
  1046. // Determine if the model has changed since the last `"change"` event.
  1047. // If you specify an attribute name, determine if that attribute has changed.
  1048. hasChanged : function(attr) {
  1049. if (attr) return this._previousAttributes[attr] != this.attributes[attr];
  1050. return this._changed;
  1051. },
  1052. // Return an object containing all the attributes that have changed, or false
  1053. // if there are no changed attributes. Useful for determining what parts of a
  1054. // view need to be updated and/or what attributes need to be persisted to
  1055. // the server.
  1056. changedAttributes : function(now) {
  1057. now || (now = this.attributes);
  1058. var old = this._previousAttributes;
  1059. var changed = false;
  1060. for (var attr in now) {
  1061. if (!_.isEqual(old[attr], now[attr])) {
  1062. changed = changed || {};
  1063. changed[attr] = now[attr];
  1064. }
  1065. }
  1066. return changed;
  1067. },
  1068. // Get the previous value of an attribute, recorded at the time the last
  1069. // `"change"` event was fired.
  1070. previous : function(attr) {
  1071. if (!attr || !this._previousAttributes) return null;
  1072. return this._previousAttributes[attr];
  1073. },
  1074. // Get all of the attributes of the model at the time of the previous
  1075. // `"change"` event.
  1076. previousAttributes : function() {
  1077. return _.clone(this._previousAttributes);
  1078. },
  1079. // Run validation against a set of incoming attributes, returning `true`
  1080. // if all is well. If a specific `error` callback has been passed,
  1081. // call that instead of firing the general `"error"` event.
  1082. _performValidation : function(attrs, options) {
  1083. var error = this.validate(attrs);
  1084. if (error) {
  1085. if (options.error) {
  1086. options.error(this, error, options);
  1087. } else {
  1088. this.trigger('error', this, error, options);
  1089. }
  1090. return false;
  1091. }
  1092. return true;
  1093. }
  1094. });
  1095. // Backbone.Collection
  1096. // -------------------
  1097. // Provides a standard collection class for our sets of models, ordered
  1098. // or unordered. If a `comparator` is specified, the Collection will maintain
  1099. // its models in sort order, as they're added and removed.
  1100. Backbone.Collection = function(models, options) {
  1101. options || (options = {});
  1102. if (options.comparator) this.comparator = options.comparator;
  1103. _.bindAll(this, '_onModelEvent', '_removeReference');
  1104. this._reset();
  1105. if (models) this.reset(models, {silent: true});
  1106. this.initialize.apply(this, arguments);
  1107. };
  1108. // Define the Collection's inheritable methods.
  1109. _.extend(Backbone.Collection.prototype, Backbone.Events, {
  1110. // The default model for a collection is just a **Backbone.Model**.
  1111. // This should be overridden in most cases.
  1112. model : Backbone.Model,
  1113. // Initialize is an empty function by default. Override it with your own
  1114. // initialization logic.
  1115. initialize : function(){},
  1116. // The JSON representation of a Collection is an array of the
  1117. // models' attributes.
  1118. toJSON : function() {
  1119. return this.map(function(model){ return model.toJSON(); });
  1120. },
  1121. // Add a model, or list of models to the set. Pass **silent** to avoid
  1122. // firing the `added` event for every new model.
  1123. add : function(models, options) {
  1124. if (_.isArray(models)) {
  1125. for (var i = 0, l = models.length; i < l; i++) {
  1126. this._add(models[i], options);
  1127. }
  1128. } else {
  1129. this._add(models, options);
  1130. }
  1131. return this;
  1132. },
  1133. // Remove a model, or a list of models from the set. Pass silent to avoid
  1134. // firing the `removed` event for every model removed.
  1135. remove : function(models, options) {
  1136. if (_.isArray(models)) {
  1137. for (var i = 0, l = models.length; i < l; i++) {
  1138. this._remove(models[i], options);
  1139. }
  1140. } else {
  1141. this._remove(models, options);
  1142. }
  1143. return this;
  1144. },
  1145. // Get a model from the set by id.
  1146. get : function(id) {
  1147. if (id == null) return null;
  1148. return this._byId[id.id != null ? id.id : id];
  1149. },
  1150. // Get a model from the set by client id.
  1151. getByCid : function(cid) {
  1152. return cid && this._byCid[cid.cid || cid];
  1153. },
  1154. // Get the model at the given index.
  1155. at: function(index) {
  1156. return this.models[index];
  1157. },
  1158. // Force the collection to re-sort itself. You don't need to call this under normal
  1159. // circumstances, as the set will maintain sort order as each item is added.
  1160. sort : function(options) {
  1161. options || (options = {});
  1162. if (!this.comparator) throw new Error('Cannot sort a set without a comparator');
  1163. this.models = this.sortBy(this.comparator);
  1164. if (!options.silent) this.trigger('reset', this, options);
  1165. return this;
  1166. },
  1167. // Pluck an attribute from each model in the collection.
  1168. pluck : function(attr) {
  1169. return _.map(this.models, function(model){ return model.get(attr); });
  1170. },
  1171. // When you have more items than you want to add or remove individually,
  1172. // you can reset the entire set with a new list of models, without firing
  1173. // any `added` or `removed` events. Fires `reset` when finished.
  1174. reset : function(models, options) {
  1175. models || (models = []);
  1176. options || (options = {});
  1177. this.each(this._removeReference);
  1178. this._reset();
  1179. this.add(models, {silent: true});
  1180. if (!options.silent) this.trigger('reset', this, options);
  1181. return this;
  1182. },
  1183. // Fetch the default set of models for this collection, resetting the
  1184. // collection when they arrive. If `add: true` is passed, appends the
  1185. // models to the collection instead of resetting.
  1186. fetch : function(options) {
  1187. options || (options = {});
  1188. var collection = this;
  1189. var success = options.success;
  1190. options.success = function(resp, status, xhr) {
  1191. collection[options.add ? 'add' : 'reset'](collection.parse(resp, xhr), options);
  1192. if (success) success(collection, resp);
  1193. };
  1194. options.error = wrapError(options.error, collection, options);
  1195. return (this.sync || Backbone.sync).call(this, 'read', this, options);
  1196. },
  1197. // Create a new instance of a model in this collection. After the model
  1198. // has been created on the server, it will be added to the collection.
  1199. // Returns the model, or 'false' if validation on a new model fails.
  1200. create : function(model, options) {
  1201. var coll = this;
  1202. options || (options = {});
  1203. model = this._prepareModel(model, options);
  1204. if (!model) return false;
  1205. var success = options.success;
  1206. options.success = function(nextModel, resp, xhr) {
  1207. coll.add(nextModel, options);
  1208. if (success) success(nextModel, resp, xhr);
  1209. };
  1210. model.save(null, options);
  1211. return model;
  1212. },
  1213. // **parse** converts a response into a list of models to be added to the
  1214. // collection. The default implementation is just to pass it through.
  1215. parse : function(resp, xhr) {
  1216. return resp;
  1217. },
  1218. // Proxy to _'s chain. Can't be proxied the same way the rest of the
  1219. // underscore methods are proxied because it relies on the underscore
  1220. // constructor.
  1221. chain: function () {
  1222. return _(this.models).chain();
  1223. },
  1224. // Reset all internal state. Called when the collection is reset.
  1225. _reset : function(options) {
  1226. this.length = 0;
  1227. this.models = [];
  1228. this._byId = {};
  1229. this._byCid = {};
  1230. },
  1231. // Prepare a model to be added to this collection
  1232. _prepareModel: function(model, options) {
  1233. if (!(model instanceof Backbone.Model)) {
  1234. var attrs = model;
  1235. model = new this.model(attrs, {collection: this});
  1236. if (model.validate && !model._performValidation(attrs, options)) model = false;
  1237. } else if (!model.collection) {
  1238. model.collection = this;
  1239. }
  1240. return model;
  1241. },
  1242. // Internal implementation of adding a single model to the set, updating
  1243. // hash indexes for `id` and `cid` lookups.
  1244. // Returns the model, or 'false' if validation on a new model fails.
  1245. _add : function(model, options) {
  1246. options |

Large files files are truncated, but you can click here to view the full file