js_stack 0.5.7 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (23) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +12 -0
  3. data/README.md +7 -7
  4. data/lib/js_stack/version.rb +1 -1
  5. data/vendor/assets/javascripts/js_stack/base/marionette/{1.8.0.js → 1.8.3.js} +173 -8
  6. data/vendor/assets/javascripts/js_stack/base/marionette.js +1 -1
  7. data/vendor/assets/javascripts/js_stack/plugins/backbone/stickit/0.8.0.js +595 -0
  8. data/vendor/assets/javascripts/js_stack/plugins/backbone.stickit.js +1 -1
  9. metadata +4 -17
  10. data/vendor/assets/javascripts/js_stack/base/backbone/1.1.0.js +0 -1581
  11. data/vendor/assets/javascripts/js_stack/base/backbone/1.1.1.js +0 -1609
  12. data/vendor/assets/javascripts/js_stack/base/marionette/1.6.2.js +0 -2555
  13. data/vendor/assets/javascripts/js_stack/base/marionette/1.7.0.js +0 -2746
  14. data/vendor/assets/javascripts/js_stack/base/marionette/1.7.3.js +0 -2765
  15. data/vendor/assets/javascripts/js_stack/plugins/backbone/associations/0.5.1.js +0 -533
  16. data/vendor/assets/javascripts/js_stack/plugins/backbone/associations/0.5.4.js +0 -574
  17. data/vendor/assets/javascripts/js_stack/plugins/backbone/mutators/0.4.1.js +0 -207
  18. data/vendor/assets/javascripts/js_stack/plugins/backbone/pageable/1.4.5.js +0 -1318
  19. data/vendor/assets/javascripts/js_stack/plugins/backbone/virtualcollection/0.4.11.js +0 -345
  20. data/vendor/assets/javascripts/js_stack/plugins/backbone/virtualcollection/0.4.12.js +0 -351
  21. data/vendor/assets/javascripts/js_stack/plugins/backbone/virtualcollection/0.4.14.js +0 -398
  22. data/vendor/assets/javascripts/js_stack/plugins/backbone/virtualcollection/0.4.5.js +0 -293
  23. data/vendor/assets/javascripts/js_stack/plugins/backbone/virtualcollection/0.4.8.js +0 -340
@@ -1,1318 +0,0 @@
1
- /*
2
- backbone-pageable 1.4.5
3
- http://github.com/backbone-paginator/backbone-pageable
4
-
5
- Copyright (c) 2013 Jimmy Yuen Ho Wong
6
- Licensed under the MIT @license.
7
- */
8
-
9
- (function (factory) {
10
-
11
- // CommonJS
12
- if (typeof exports == "object") {
13
- module.exports = factory(require("underscore"), require("backbone"));
14
- }
15
- // AMD
16
- else if (typeof define == "function" && define.amd) {
17
- define(["underscore", "backbone"], factory);
18
- }
19
- // Browser
20
- else if (typeof _ !== "undefined" && typeof Backbone !== "undefined") {
21
- var oldPageableCollection = Backbone.PageableCollection;
22
- var PageableCollection = factory(_, Backbone);
23
-
24
- /**
25
- __BROWSER ONLY__
26
-
27
- If you already have an object named `PageableCollection` attached to the
28
- `Backbone` module, you can use this to return a local reference to this
29
- Backbone.PageableCollection class and reset the name
30
- Backbone.PageableCollection to its previous definition.
31
-
32
- // The left hand side gives you a reference to this
33
- // Backbone.PageableCollection implementation, the right hand side
34
- // resets Backbone.PageableCollection to your other
35
- // Backbone.PageableCollection.
36
- var PageableCollection = Backbone.PageableCollection.noConflict();
37
-
38
- @static
39
- @member Backbone.PageableCollection
40
- @return {Backbone.PageableCollection}
41
- */
42
- Backbone.PageableCollection.noConflict = function () {
43
- Backbone.PageableCollection = oldPageableCollection;
44
- return PageableCollection;
45
- };
46
- }
47
-
48
- }(function (_, Backbone) {
49
-
50
- "use strict";
51
-
52
- var _extend = _.extend;
53
- var _omit = _.omit;
54
- var _clone = _.clone;
55
- var _each = _.each;
56
- var _pick = _.pick;
57
- var _contains = _.contains;
58
- var _isEmpty = _.isEmpty;
59
- var _pairs = _.pairs;
60
- var _invert = _.invert;
61
- var _isArray = _.isArray;
62
- var _isFunction = _.isFunction;
63
- var _isObject = _.isObject;
64
- var _keys = _.keys;
65
- var _isUndefined = _.isUndefined;
66
- var _result = _.result;
67
- var ceil = Math.ceil;
68
- var floor = Math.floor;
69
- var max = Math.max;
70
-
71
- var BBColProto = Backbone.Collection.prototype;
72
-
73
- function finiteInt (val, name) {
74
- if (!_.isNumber(val) || _.isNaN(val) || !_.isFinite(val) || ~~val !== val) {
75
- throw new TypeError("`" + name + "` must be a finite integer");
76
- }
77
- return val;
78
- }
79
-
80
- function queryStringToParams (qs) {
81
- var kvp, k, v, ls, params = {}, decode = decodeURIComponent;
82
- var kvps = qs.split('&');
83
- for (var i = 0, l = kvps.length; i < l; i++) {
84
- var param = kvps[i];
85
- kvp = param.split('='), k = kvp[0], v = kvp[1] || true;
86
- k = decode(k), v = decode(v), ls = params[k];
87
- if (_isArray(ls)) ls.push(v);
88
- else if (ls) params[k] = [ls, v];
89
- else params[k] = v;
90
- }
91
- return params;
92
- }
93
-
94
- // hack to make sure the whatever event handlers for this event is run
95
- // before func is, and the event handlers that func will trigger.
96
- function runOnceAtLastHandler (col, event, func) {
97
- var eventHandlers = col._events[event];
98
- if (eventHandlers && eventHandlers.length) {
99
- var lastHandler = eventHandlers[eventHandlers.length - 1];
100
- var oldCallback = lastHandler.callback;
101
- lastHandler.callback = function () {
102
- try {
103
- oldCallback.apply(this, arguments);
104
- func();
105
- }
106
- catch (e) {
107
- throw e;
108
- }
109
- finally {
110
- lastHandler.callback = oldCallback;
111
- }
112
- };
113
- }
114
- else func();
115
- }
116
-
117
- var PARAM_TRIM_RE = /[\s'"]/g;
118
- var URL_TRIM_RE = /[<>\s'"]/g;
119
-
120
- /**
121
- Drop-in replacement for Backbone.Collection. Supports server-side and
122
- client-side pagination and sorting. Client-side mode also support fully
123
- multi-directional synchronization of changes between pages.
124
-
125
- @class Backbone.PageableCollection
126
- @extends Backbone.Collection
127
- */
128
- var PageableCollection = Backbone.PageableCollection = Backbone.Collection.extend({
129
-
130
- /**
131
- The container object to store all pagination states.
132
-
133
- You can override the default state by extending this class or specifying
134
- them in an `options` hash to the constructor.
135
-
136
- @property {Object} state
137
-
138
- @property {0|1} [state.firstPage=1] The first page index. Set to 0 if
139
- your server API uses 0-based indices. You should only override this value
140
- during extension, initialization or reset by the server after
141
- fetching. This value should be read only at other times.
142
-
143
- @property {number} [state.lastPage=null] The last page index. This value
144
- is __read only__ and it's calculated based on whether `firstPage` is 0 or
145
- 1, during bootstrapping, fetching and resetting. Please don't change this
146
- value under any circumstances.
147
-
148
- @property {number} [state.currentPage=null] The current page index. You
149
- should only override this value during extension, initialization or reset
150
- by the server after fetching. This value should be read only at other
151
- times. Can be a 0-based or 1-based index, depending on whether
152
- `firstPage` is 0 or 1. If left as default, it will be set to `firstPage`
153
- on initialization.
154
-
155
- @property {number} [state.pageSize=25] How many records to show per
156
- page. This value is __read only__ after initialization, if you want to
157
- change the page size after initialization, you must call #setPageSize.
158
-
159
- @property {number} [state.totalPages=null] How many pages there are. This
160
- value is __read only__ and it is calculated from `totalRecords`.
161
-
162
- @property {number} [state.totalRecords=null] How many records there
163
- are. This value is __required__ under server mode. This value is optional
164
- for client mode as the number will be the same as the number of models
165
- during bootstrapping and during fetching, either supplied by the server
166
- in the metadata, or calculated from the size of the response.
167
-
168
- @property {string} [state.sortKey=null] The model attribute to use for
169
- sorting.
170
-
171
- @property {-1|0|1} [state.order=-1] The order to use for sorting. Specify
172
- -1 for ascending order or 1 for descending order. If 0, no client side
173
- sorting will be done and the order query parameter will not be sent to
174
- the server during a fetch.
175
- */
176
- state: {
177
- firstPage: 1,
178
- lastPage: null,
179
- currentPage: null,
180
- pageSize: 25,
181
- totalPages: null,
182
- totalRecords: null,
183
- sortKey: null,
184
- order: -1
185
- },
186
-
187
- /**
188
- @property {"server"|"client"|"infinite"} [mode="server"] The mode of
189
- operations for this collection. `"server"` paginates on the server-side,
190
- `"client"` paginates on the client-side and `"infinite"` paginates on the
191
- server-side for APIs that do not support `totalRecords`.
192
- */
193
- mode: "server",
194
-
195
- /**
196
- A translation map to convert Backbone.PageableCollection state attributes
197
- to the query parameters accepted by your server API.
198
-
199
- You can override the default state by extending this class or specifying
200
- them in `options.queryParams` object hash to the constructor.
201
-
202
- @property {Object} queryParams
203
- @property {string} [queryParams.currentPage="page"]
204
- @property {string} [queryParams.pageSize="per_page"]
205
- @property {string} [queryParams.totalPages="total_pages"]
206
- @property {string} [queryParams.totalRecords="total_entries"]
207
- @property {string} [queryParams.sortKey="sort_by"]
208
- @property {string} [queryParams.order="order"]
209
- @property {string} [queryParams.directions={"-1": "asc", "1": "desc"}] A
210
- map for translating a Backbone.PageableCollection#state.order constant to
211
- the ones your server API accepts.
212
- */
213
- queryParams: {
214
- currentPage: "page",
215
- pageSize: "per_page",
216
- totalPages: "total_pages",
217
- totalRecords: "total_entries",
218
- sortKey: "sort_by",
219
- order: "order",
220
- directions: {
221
- "-1": "asc",
222
- "1": "desc"
223
- }
224
- },
225
-
226
- /**
227
- __CLIENT MODE ONLY__
228
-
229
- This collection is the internal storage for the bootstrapped or fetched
230
- models. You can use this if you want to operate on all the pages.
231
-
232
- @property {Backbone.Collection} fullCollection
233
- */
234
-
235
- /**
236
- Given a list of models or model attributues, bootstraps the full
237
- collection in client mode or infinite mode, or just the page you want in
238
- server mode.
239
-
240
- If you want to initialize a collection to a different state than the
241
- default, you can specify them in `options.state`. Any state parameters
242
- supplied will be merged with the default. If you want to change the
243
- default mapping from #state keys to your server API's query parameter
244
- names, you can specifiy an object hash in `option.queryParams`. Likewise,
245
- any mapping provided will be merged with the default. Lastly, all
246
- Backbone.Collection constructor options are also accepted.
247
-
248
- See:
249
-
250
- - Backbone.PageableCollection#state
251
- - Backbone.PageableCollection#queryParams
252
- - [Backbone.Collection#initialize](http://backbonejs.org/#Collection-constructor)
253
-
254
- @param {Array.<Object>} [models]
255
-
256
- @param {Object} [options]
257
-
258
- @param {function(*, *): number} [options.comparator] If specified, this
259
- comparator is set to the current page under server mode, or the #fullCollection
260
- otherwise.
261
-
262
- @param {boolean} [options.full] If `false` and either a
263
- `options.comparator` or `sortKey` is defined, the comparator is attached
264
- to the current page. Default is `true` under client or infinite mode and
265
- the comparator will be attached to the #fullCollection.
266
-
267
- @param {Object} [options.state] The state attributes overriding the defaults.
268
-
269
- @param {string} [options.state.sortKey] The model attribute to use for
270
- sorting. If specified instead of `options.comparator`, a comparator will
271
- be automatically created using this value, and optionally a sorting order
272
- specified in `options.state.order`. The comparator is then attached to
273
- the new collection instance.
274
-
275
- @param {-1|1} [options.state.order] The order to use for sorting. Specify
276
- -1 for ascending order and 1 for descending order.
277
-
278
- @param {Object} [options.queryParam]
279
- */
280
- constructor: function (models, options) {
281
-
282
- BBColProto.constructor.apply(this, arguments);
283
-
284
- options = options || {};
285
-
286
- var mode = this.mode = options.mode || this.mode || PageableProto.mode;
287
-
288
- var queryParams = _extend({}, PageableProto.queryParams, this.queryParams,
289
- options.queryParams || {});
290
-
291
- queryParams.directions = _extend({},
292
- PageableProto.queryParams.directions,
293
- this.queryParams.directions,
294
- queryParams.directions || {});
295
-
296
- this.queryParams = queryParams;
297
-
298
- var state = this.state = _extend({}, PageableProto.state, this.state,
299
- options.state || {});
300
-
301
- state.currentPage = state.currentPage == null ?
302
- state.firstPage :
303
- state.currentPage;
304
-
305
- if (!_isArray(models)) models = models ? [models] : [];
306
-
307
- if (mode != "server" && state.totalRecords == null && !_isEmpty(models)) {
308
- state.totalRecords = models.length;
309
- }
310
-
311
- this.switchMode(mode, _extend({fetch: false,
312
- resetState: false,
313
- models: models}, options));
314
-
315
- var comparator = options.comparator;
316
-
317
- if (state.sortKey && !comparator) {
318
- this.setSorting(state.sortKey, state.order, options);
319
- }
320
-
321
- if (mode != "server") {
322
- var fullCollection = this.fullCollection;
323
-
324
- if (comparator && options.full) {
325
- this.comparator = null;
326
- fullCollection.comparator = comparator;
327
- }
328
-
329
- if (options.full) fullCollection.sort();
330
-
331
- // make sure the models in the current page and full collection have the
332
- // same references
333
- if (models && !_isEmpty(models)) {
334
- this.reset([].slice.call(models), _extend({silent: true}, options));
335
- this.getPage(state.currentPage);
336
- models.splice.apply(models, [0, models.length].concat(this.models));
337
- }
338
- }
339
-
340
- this._initState = _clone(this.state);
341
- },
342
-
343
- /**
344
- Makes a Backbone.Collection that contains all the pages.
345
-
346
- @private
347
- @param {Array.<Object|Backbone.Model>} models
348
- @param {Object} options Options for Backbone.Collection constructor.
349
- @return {Backbone.Collection}
350
- */
351
- _makeFullCollection: function (models, options) {
352
-
353
- var properties = ["url", "model", "sync", "comparator"];
354
- var thisProto = this.constructor.prototype;
355
- var i, length, prop;
356
-
357
- var proto = {};
358
- for (i = 0, length = properties.length; i < length; i++) {
359
- prop = properties[i];
360
- if (!_isUndefined(thisProto[prop])) {
361
- proto[prop] = thisProto[prop];
362
- }
363
- }
364
-
365
- var fullCollection = new (Backbone.Collection.extend(proto))(models, options);
366
-
367
- for (i = 0, length = properties.length; i < length; i++) {
368
- prop = properties[i];
369
- if (this[prop] !== thisProto[prop]) {
370
- fullCollection[prop] = this[prop];
371
- }
372
- }
373
-
374
- return fullCollection;
375
- },
376
-
377
- /**
378
- Factory method that returns a Backbone event handler that responses to
379
- the `add`, `remove`, `reset`, and the `sort` events. The returned event
380
- handler will synchronize the current page collection and the full
381
- collection's models.
382
-
383
- @private
384
-
385
- @param {Backbone.PageableCollection} pageCol
386
- @param {Backbone.Collection} fullCol
387
-
388
- @return {function(string, Backbone.Model, Backbone.Collection, Object)}
389
- Collection event handler
390
- */
391
- _makeCollectionEventHandler: function (pageCol, fullCol) {
392
-
393
- return function collectionEventHandler (event, model, collection, options) {
394
-
395
- var handlers = pageCol._handlers;
396
- _each(_keys(handlers), function (event) {
397
- var handler = handlers[event];
398
- pageCol.off(event, handler);
399
- fullCol.off(event, handler);
400
- });
401
-
402
- var state = _clone(pageCol.state);
403
- var firstPage = state.firstPage;
404
- var currentPage = firstPage === 0 ?
405
- state.currentPage :
406
- state.currentPage - 1;
407
- var pageSize = state.pageSize;
408
- var pageStart = currentPage * pageSize, pageEnd = pageStart + pageSize;
409
-
410
- if (event == "add") {
411
- var pageIndex, fullIndex, addAt, colToAdd, options = options || {};
412
- if (collection == fullCol) {
413
- fullIndex = fullCol.indexOf(model);
414
- if (fullIndex >= pageStart && fullIndex < pageEnd) {
415
- colToAdd = pageCol;
416
- pageIndex = addAt = fullIndex - pageStart;
417
- }
418
- }
419
- else {
420
- pageIndex = pageCol.indexOf(model);
421
- fullIndex = pageStart + pageIndex;
422
- colToAdd = fullCol;
423
- var addAt = !_isUndefined(options.at) ?
424
- options.at + pageStart :
425
- fullIndex;
426
- }
427
-
428
- if (!options.onRemove) {
429
- ++state.totalRecords;
430
- delete options.onRemove;
431
- }
432
-
433
- pageCol.state = pageCol._checkState(state);
434
-
435
- if (colToAdd) {
436
- colToAdd.add(model, _extend({}, options || {}, {at: addAt}));
437
- var modelToRemove = pageIndex >= pageSize ?
438
- model :
439
- !_isUndefined(options.at) && addAt < pageEnd && pageCol.length > pageSize ?
440
- pageCol.at(pageSize) :
441
- null;
442
- if (modelToRemove) {
443
- runOnceAtLastHandler(collection, event, function () {
444
- pageCol.remove(modelToRemove, {onAdd: true});
445
- });
446
- }
447
- }
448
- }
449
-
450
- // remove the model from the other collection as well
451
- if (event == "remove") {
452
- if (!options.onAdd) {
453
- // decrement totalRecords and update totalPages and lastPage
454
- if (!--state.totalRecords) {
455
- state.totalRecords = null;
456
- state.totalPages = null;
457
- }
458
- else {
459
- var totalPages = state.totalPages = ceil(state.totalRecords / pageSize);
460
- state.lastPage = firstPage === 0 ? totalPages - 1 : totalPages || firstPage;
461
- if (state.currentPage > totalPages) state.currentPage = state.lastPage;
462
- }
463
- pageCol.state = pageCol._checkState(state);
464
-
465
- var nextModel, removedIndex = options.index;
466
- if (collection == pageCol) {
467
- if (nextModel = fullCol.at(pageEnd)) {
468
- runOnceAtLastHandler(pageCol, event, function () {
469
- pageCol.push(nextModel, {onRemove: true});
470
- });
471
- }
472
- fullCol.remove(model);
473
- }
474
- else if (removedIndex >= pageStart && removedIndex < pageEnd) {
475
- if (nextModel = fullCol.at(pageEnd - 1)) {
476
- runOnceAtLastHandler(pageCol, event, function() {
477
- pageCol.push(nextModel, {onRemove: true});
478
- });
479
- }
480
- pageCol.remove(model);
481
- }
482
- }
483
- else delete options.onAdd;
484
- }
485
-
486
- if (event == "reset") {
487
- options = collection;
488
- collection = model;
489
-
490
- // Reset that's not a result of getPage
491
- if (collection == pageCol && options.from == null &&
492
- options.to == null) {
493
- var head = fullCol.models.slice(0, pageStart);
494
- var tail = fullCol.models.slice(pageStart + pageCol.models.length);
495
- fullCol.reset(head.concat(pageCol.models).concat(tail), options);
496
- }
497
- else if (collection == fullCol) {
498
- if (!(state.totalRecords = fullCol.models.length)) {
499
- state.totalRecords = null;
500
- state.totalPages = null;
501
- }
502
- if (pageCol.mode == "client") {
503
- state.lastPage = state.currentPage = state.firstPage;
504
- }
505
- pageCol.state = pageCol._checkState(state);
506
- pageCol.reset(fullCol.models.slice(pageStart, pageEnd),
507
- _extend({}, options, {parse: false}));
508
- }
509
- }
510
-
511
- if (event == "sort") {
512
- options = collection;
513
- collection = model;
514
- if (collection === fullCol) {
515
- pageCol.reset(fullCol.models.slice(pageStart, pageEnd),
516
- _extend({}, options, {parse: false}));
517
- }
518
- }
519
-
520
- _each(_keys(handlers), function (event) {
521
- var handler = handlers[event];
522
- _each([pageCol, fullCol], function (col) {
523
- col.on(event, handler);
524
- var callbacks = col._events[event] || [];
525
- callbacks.unshift(callbacks.pop());
526
- });
527
- });
528
- };
529
- },
530
-
531
- /**
532
- Sanity check this collection's pagination states. Only perform checks
533
- when all the required pagination state values are defined and not null.
534
- If `totalPages` is undefined or null, it is set to `totalRecords` /
535
- `pageSize`. `lastPage` is set according to whether `firstPage` is 0 or 1
536
- when no error occurs.
537
-
538
- @private
539
-
540
- @throws {TypeError} If `totalRecords`, `pageSize`, `currentPage` or
541
- `firstPage` is not a finite integer.
542
-
543
- @throws {RangeError} If `pageSize`, `currentPage` or `firstPage` is out
544
- of bounds.
545
-
546
- @return {Object} Returns the `state` object if no error was found.
547
- */
548
- _checkState: function (state) {
549
-
550
- var mode = this.mode;
551
- var links = this.links;
552
- var totalRecords = state.totalRecords;
553
- var pageSize = state.pageSize;
554
- var currentPage = state.currentPage;
555
- var firstPage = state.firstPage;
556
- var totalPages = state.totalPages;
557
-
558
- if (totalRecords != null && pageSize != null && currentPage != null &&
559
- firstPage != null && (mode == "infinite" ? links : true)) {
560
-
561
- totalRecords = finiteInt(totalRecords, "totalRecords");
562
- pageSize = finiteInt(pageSize, "pageSize");
563
- currentPage = finiteInt(currentPage, "currentPage");
564
- firstPage = finiteInt(firstPage, "firstPage");
565
-
566
- if (pageSize < 1) {
567
- throw new RangeError("`pageSize` must be >= 1");
568
- }
569
-
570
- totalPages = state.totalPages = ceil(totalRecords / pageSize);
571
-
572
- if (firstPage < 0 || firstPage > 1) {
573
- throw new RangeError("`firstPage must be 0 or 1`");
574
- }
575
-
576
- state.lastPage = firstPage === 0 ? max(0, totalPages - 1) : totalPages || firstPage;
577
-
578
- if (mode == "infinite") {
579
- if (!links[currentPage + '']) {
580
- throw new RangeError("No link found for page " + currentPage);
581
- }
582
- }
583
- else if (currentPage < firstPage ||
584
- (totalPages > 0 &&
585
- (firstPage ? currentPage > totalPages : currentPage >= totalPages))) {
586
- throw new RangeError("`currentPage` must be firstPage <= currentPage " +
587
- (firstPage ? ">" : ">=") +
588
- " totalPages if " + firstPage + "-based. Got " +
589
- currentPage + '.');
590
- }
591
- }
592
-
593
- return state;
594
- },
595
-
596
- /**
597
- Change the page size of this collection.
598
-
599
- Under most if not all circumstances, you should call this method to
600
- change the page size of a pageable collection because it will keep the
601
- pagination state sane. By default, the method will recalculate the
602
- current page number to one that will retain the current page's models
603
- when increasing the page size. When decreasing the page size, this method
604
- will retain the last models to the current page that will fit into the
605
- smaller page size.
606
-
607
- If `options.first` is true, changing the page size will also reset the
608
- current page back to the first page instead of trying to be smart.
609
-
610
- For server mode operations, changing the page size will trigger a #fetch
611
- and subsequently a `reset` event.
612
-
613
- For client mode operations, changing the page size will `reset` the
614
- current page by recalculating the current page boundary on the client
615
- side.
616
-
617
- If `options.fetch` is true, a fetch can be forced if the collection is in
618
- client mode.
619
-
620
- @param {number} pageSize The new page size to set to #state.
621
- @param {Object} [options] {@link #fetch} options.
622
- @param {boolean} [options.first=false] Reset the current page number to
623
- the first page if `true`.
624
- @param {boolean} [options.fetch] If `true`, force a fetch in client mode.
625
-
626
- @throws {TypeError} If `pageSize` is not a finite integer.
627
- @throws {RangeError} If `pageSize` is less than 1.
628
-
629
- @chainable
630
- @return {XMLHttpRequest|Backbone.PageableCollection} The XMLHttpRequest
631
- from fetch or this.
632
- */
633
- setPageSize: function (pageSize, options) {
634
- pageSize = finiteInt(pageSize, "pageSize");
635
-
636
- options = options || {first: false};
637
-
638
- var state = this.state;
639
- var totalPages = ceil(state.totalRecords / pageSize);
640
- var currentPage = totalPages ?
641
- max(state.firstPage,
642
- floor(totalPages *
643
- (state.firstPage ?
644
- state.currentPage :
645
- state.currentPage + 1) /
646
- state.totalPages)) :
647
- state.firstPage;
648
-
649
- state = this.state = this._checkState(_extend({}, state, {
650
- pageSize: pageSize,
651
- currentPage: options.first ? state.firstPage : currentPage,
652
- totalPages: totalPages
653
- }));
654
-
655
- return this.getPage(state.currentPage, _omit(options, ["first"]));
656
- },
657
-
658
- /**
659
- Switching between client, server and infinite mode.
660
-
661
- If switching from client to server mode, the #fullCollection is emptied
662
- first and then deleted and a fetch is immediately issued for the current
663
- page from the server. Pass `false` to `options.fetch` to skip fetching.
664
-
665
- If switching to infinite mode, and if `options.models` is given for an
666
- array of models, #links will be populated with a URL per page, using the
667
- default URL for this collection.
668
-
669
- If switching from server to client mode, all of the pages are immediately
670
- refetched. If you have too many pages, you can pass `false` to
671
- `options.fetch` to skip fetching.
672
-
673
- If switching to any mode from infinite mode, the #links will be deleted.
674
-
675
- @param {"server"|"client"|"infinite"} [mode] The mode to switch to.
676
-
677
- @param {Object} [options]
678
-
679
- @param {boolean} [options.fetch=true] If `false`, no fetching is done.
680
-
681
- @param {boolean} [options.resetState=true] If 'false', the state is not
682
- reset, but checked for sanity instead.
683
-
684
- @chainable
685
- @return {XMLHttpRequest|Backbone.PageableCollection} The XMLHttpRequest
686
- from fetch or this if `options.fetch` is `false`.
687
- */
688
- switchMode: function (mode, options) {
689
-
690
- if (!_contains(["server", "client", "infinite"], mode)) {
691
- throw new TypeError('`mode` must be one of "server", "client" or "infinite"');
692
- }
693
-
694
- options = options || {fetch: true, resetState: true};
695
-
696
- var state = this.state = options.resetState ?
697
- _clone(this._initState) :
698
- this._checkState(_extend({}, this.state));
699
-
700
- this.mode = mode;
701
-
702
- var self = this;
703
- var fullCollection = this.fullCollection;
704
- var handlers = this._handlers = this._handlers || {}, handler;
705
- if (mode != "server" && !fullCollection) {
706
- fullCollection = this._makeFullCollection(options.models || [], options);
707
- fullCollection.pageableCollection = this;
708
- this.fullCollection = fullCollection;
709
- var allHandler = this._makeCollectionEventHandler(this, fullCollection);
710
- _each(["add", "remove", "reset", "sort"], function (event) {
711
- handlers[event] = handler = _.bind(allHandler, {}, event);
712
- self.on(event, handler);
713
- fullCollection.on(event, handler);
714
- });
715
- fullCollection.comparator = this._fullComparator;
716
- }
717
- else if (mode == "server" && fullCollection) {
718
- _each(_keys(handlers), function (event) {
719
- handler = handlers[event];
720
- self.off(event, handler);
721
- fullCollection.off(event, handler);
722
- });
723
- delete this._handlers;
724
- this._fullComparator = fullCollection.comparator;
725
- delete this.fullCollection;
726
- }
727
-
728
- if (mode == "infinite") {
729
- var links = this.links = {};
730
- var firstPage = state.firstPage;
731
- var totalPages = ceil(state.totalRecords / state.pageSize);
732
- var lastPage = firstPage === 0 ? max(0, totalPages - 1) : totalPages || firstPage;
733
- for (var i = state.firstPage; i <= lastPage; i++) {
734
- links[i] = this.url;
735
- }
736
- }
737
- else if (this.links) delete this.links;
738
-
739
- return options.fetch ?
740
- this.fetch(_omit(options, "fetch", "resetState")) :
741
- this;
742
- },
743
-
744
- /**
745
- @return {boolean} `true` if this collection can page backward, `false`
746
- otherwise.
747
- */
748
- hasPrevious: function () {
749
- var state = this.state;
750
- var currentPage = state.currentPage;
751
- if (this.mode != "infinite") return currentPage > state.firstPage;
752
- return !!this.links[currentPage - 1];
753
- },
754
-
755
- /**
756
- @return {boolean} `true` if this collection can page forward, `false`
757
- otherwise.
758
- */
759
- hasNext: function () {
760
- var state = this.state;
761
- var currentPage = this.state.currentPage;
762
- if (this.mode != "infinite") return currentPage < state.lastPage;
763
- return !!this.links[currentPage + 1];
764
- },
765
-
766
- /**
767
- Fetch the first page in server mode, or reset the current page of this
768
- collection to the first page in client or infinite mode.
769
-
770
- @param {Object} options {@link #getPage} options.
771
-
772
- @chainable
773
- @return {XMLHttpRequest|Backbone.PageableCollection} The XMLHttpRequest
774
- from fetch or this.
775
- */
776
- getFirstPage: function (options) {
777
- return this.getPage("first", options);
778
- },
779
-
780
- /**
781
- Fetch the previous page in server mode, or reset the current page of this
782
- collection to the previous page in client or infinite mode.
783
-
784
- @param {Object} options {@link #getPage} options.
785
-
786
- @chainable
787
- @return {XMLHttpRequest|Backbone.PageableCollection} The XMLHttpRequest
788
- from fetch or this.
789
- */
790
- getPreviousPage: function (options) {
791
- return this.getPage("prev", options);
792
- },
793
-
794
- /**
795
- Fetch the next page in server mode, or reset the current page of this
796
- collection to the next page in client mode.
797
-
798
- @param {Object} options {@link #getPage} options.
799
-
800
- @chainable
801
- @return {XMLHttpRequest|Backbone.PageableCollection} The XMLHttpRequest
802
- from fetch or this.
803
- */
804
- getNextPage: function (options) {
805
- return this.getPage("next", options);
806
- },
807
-
808
- /**
809
- Fetch the last page in server mode, or reset the current page of this
810
- collection to the last page in client mode.
811
-
812
- @param {Object} options {@link #getPage} options.
813
-
814
- @chainable
815
- @return {XMLHttpRequest|Backbone.PageableCollection} The XMLHttpRequest
816
- from fetch or this.
817
- */
818
- getLastPage: function (options) {
819
- return this.getPage("last", options);
820
- },
821
-
822
- /**
823
- Given a page index, set #state.currentPage to that index. If this
824
- collection is in server mode, fetch the page using the updated state,
825
- otherwise, reset the current page of this collection to the page
826
- specified by `index` in client mode. If `options.fetch` is true, a fetch
827
- can be forced in client mode before resetting the current page. Under
828
- infinite mode, if the index is less than the current page, a reset is
829
- done as in client mode. If the index is greater than the current page
830
- number, a fetch is made with the results **appended** to #fullCollection.
831
- The current page will then be reset after fetching.
832
-
833
- @param {number|string} index The page index to go to, or the page name to
834
- look up from #links in infinite mode.
835
- @param {Object} [options] {@link #fetch} options or
836
- [reset](http://backbonejs.org/#Collection-reset) options for client mode
837
- when `options.fetch` is `false`.
838
- @param {boolean} [options.fetch=false] If true, force a {@link #fetch} in
839
- client mode.
840
-
841
- @throws {TypeError} If `index` is not a finite integer under server or
842
- client mode, or does not yield a URL from #links under infinite mode.
843
-
844
- @throws {RangeError} If `index` is out of bounds.
845
-
846
- @chainable
847
- @return {XMLHttpRequest|Backbone.PageableCollection} The XMLHttpRequest
848
- from fetch or this.
849
- */
850
- getPage: function (index, options) {
851
-
852
- var mode = this.mode, fullCollection = this.fullCollection;
853
-
854
- options = options || {fetch: false};
855
-
856
- var state = this.state,
857
- firstPage = state.firstPage,
858
- currentPage = state.currentPage,
859
- lastPage = state.lastPage,
860
- pageSize = state.pageSize;
861
-
862
- var pageNum = index;
863
- switch (index) {
864
- case "first": pageNum = firstPage; break;
865
- case "prev": pageNum = currentPage - 1; break;
866
- case "next": pageNum = currentPage + 1; break;
867
- case "last": pageNum = lastPage; break;
868
- default: pageNum = finiteInt(index, "index");
869
- }
870
-
871
- this.state = this._checkState(_extend({}, state, {currentPage: pageNum}));
872
-
873
- options.from = currentPage, options.to = pageNum;
874
-
875
- var pageStart = (firstPage === 0 ? pageNum : pageNum - 1) * pageSize;
876
- var pageModels = fullCollection && fullCollection.length ?
877
- fullCollection.models.slice(pageStart, pageStart + pageSize) :
878
- [];
879
- if ((mode == "client" || (mode == "infinite" && !_isEmpty(pageModels))) &&
880
- !options.fetch) {
881
- this.reset(pageModels, _omit(options, "fetch"));
882
- return this;
883
- }
884
-
885
- if (mode == "infinite") options.url = this.links[pageNum];
886
-
887
- return this.fetch(_omit(options, "fetch"));
888
- },
889
-
890
- /**
891
- Fetch the page for the provided item offset in server mode, or reset the current page of this
892
- collection to the page for the provided item offset in client mode.
893
-
894
- @param {Object} options {@link #getPage} options.
895
-
896
- @chainable
897
- @return {XMLHttpRequest|Backbone.PageableCollection} The XMLHttpRequest
898
- from fetch or this.
899
- */
900
- getPageByOffset: function (offset, options) {
901
- if (offset < 0) {
902
- throw new RangeError("`offset must be > 0`");
903
- }
904
- offset = finiteInt(offset);
905
-
906
- var page = floor(offset / this.state.pageSize);
907
- if (this.state.firstPage !== 0) page++;
908
- if (page > this.state.lastPage) page = this.state.lastPage;
909
- return this.getPage(page, options);
910
- },
911
-
912
- /**
913
- Overidden to make `getPage` compatible with Zepto.
914
-
915
- @param {string} method
916
- @param {Backbone.Model|Backbone.Collection} model
917
- @param {Object} [options]
918
-
919
- @return {XMLHttpRequest}
920
- */
921
- sync: function (method, model, options) {
922
- var self = this;
923
- if (self.mode == "infinite") {
924
- var success = options.success;
925
- var currentPage = self.state.currentPage;
926
- options.success = function (resp, status, xhr) {
927
- var links = self.links;
928
- var newLinks = self.parseLinks(resp, _extend({xhr: xhr}, options));
929
- if (newLinks.first) links[self.state.firstPage] = newLinks.first;
930
- if (newLinks.prev) links[currentPage - 1] = newLinks.prev;
931
- if (newLinks.next) links[currentPage + 1] = newLinks.next;
932
- if (success) success(resp, status, xhr);
933
- };
934
- }
935
-
936
- return (BBColProto.sync || Backbone.sync).call(self, method, model, options);
937
- },
938
-
939
- /**
940
- Parse pagination links from the server response. Only valid under
941
- infinite mode.
942
-
943
- Given a response body and a XMLHttpRequest object, extract pagination
944
- links from them for infinite paging.
945
-
946
- This default implementation parses the RFC 5988 `Link` header and extract
947
- 3 links from it - `first`, `prev`, `next`. Any subclasses overriding this
948
- method __must__ return an object hash having only the keys
949
- above. However, simply returning a `next` link or an empty hash if there
950
- are no more links should be enough for most implementations.
951
-
952
- @param {*} resp The deserialized response body.
953
- @param {Object} [options]
954
- @param {XMLHttpRequest} [options.xhr] The XMLHttpRequest object for this
955
- response.
956
- @return {Object}
957
- */
958
- parseLinks: function (resp, options) {
959
- var links = {};
960
- var linkHeader = options.xhr.getResponseHeader("Link");
961
- if (linkHeader) {
962
- var relations = ["first", "prev", "next"];
963
- _each(linkHeader.split(","), function (linkValue) {
964
- var linkParts = linkValue.split(";");
965
- var url = linkParts[0].replace(URL_TRIM_RE, '');
966
- var params = linkParts.slice(1);
967
- _each(params, function (param) {
968
- var paramParts = param.split("=");
969
- var key = paramParts[0].replace(PARAM_TRIM_RE, '');
970
- var value = paramParts[1].replace(PARAM_TRIM_RE, '');
971
- if (key == "rel" && _contains(relations, value)) links[value] = url;
972
- });
973
- });
974
- }
975
-
976
- return links;
977
- },
978
-
979
- /**
980
- Parse server response data.
981
-
982
- This default implementation assumes the response data is in one of two
983
- structures:
984
-
985
- [
986
- {}, // Your new pagination state
987
- [{}, ...] // An array of JSON objects
988
- ]
989
-
990
- Or,
991
-
992
- [{}] // An array of JSON objects
993
-
994
- The first structure is the preferred form because the pagination states
995
- may have been updated on the server side, sending them down again allows
996
- this collection to update its states. If the response has a pagination
997
- state object, it is checked for errors.
998
-
999
- The second structure is the
1000
- [Backbone.Collection#parse](http://backbonejs.org/#Collection-parse)
1001
- default.
1002
-
1003
- **Note:** this method has been further simplified since 1.1.7. While
1004
- existing #parse implementations will continue to work, new code is
1005
- encouraged to override #parseState and #parseRecords instead.
1006
-
1007
- @param {Object} resp The deserialized response data from the server.
1008
- @param {Object} the options for the ajax request
1009
-
1010
- @return {Array.<Object>} An array of model objects
1011
- */
1012
- parse: function (resp, options) {
1013
- var newState = this.parseState(resp, _clone(this.queryParams), _clone(this.state), options);
1014
- if (newState) this.state = this._checkState(_extend({}, this.state, newState));
1015
- return this.parseRecords(resp, options);
1016
- },
1017
-
1018
- /**
1019
- Parse server response for server pagination state updates. Not applicable
1020
- under infinite mode.
1021
-
1022
- This default implementation first checks whether the response has any
1023
- state object as documented in #parse. If it exists, a state object is
1024
- returned by mapping the server state keys to this pageable collection
1025
- instance's query parameter keys using `queryParams`.
1026
-
1027
- It is __NOT__ neccessary to return a full state object complete with all
1028
- the mappings defined in #queryParams. Any state object resulted is merged
1029
- with a copy of the current pageable collection state and checked for
1030
- sanity before actually updating. Most of the time, simply providing a new
1031
- `totalRecords` value is enough to trigger a full pagination state
1032
- recalculation.
1033
-
1034
- parseState: function (resp, queryParams, state, options) {
1035
- return {totalRecords: resp.total_entries};
1036
- }
1037
-
1038
- If you want to use header fields use:
1039
-
1040
- parseState: function (resp, queryParams, state, options) {
1041
- return {totalRecords: options.xhr.getResponseHeader("X-total")};
1042
- }
1043
-
1044
- This method __MUST__ return a new state object instead of directly
1045
- modifying the #state object. The behavior of directly modifying #state is
1046
- undefined.
1047
-
1048
- @param {Object} resp The deserialized response data from the server.
1049
- @param {Object} queryParams A copy of #queryParams.
1050
- @param {Object} state A copy of #state.
1051
- @param {Object} [options] The options passed through from
1052
- `parse`. (backbone >= 0.9.10 only)
1053
-
1054
- @return {Object} A new (partial) state object.
1055
- */
1056
- parseState: function (resp, queryParams, state, options) {
1057
- if (resp && resp.length === 2 && _isObject(resp[0]) && _isArray(resp[1])) {
1058
-
1059
- var newState = _clone(state);
1060
- var serverState = resp[0];
1061
-
1062
- _each(_pairs(_omit(queryParams, "directions")), function (kvp) {
1063
- var k = kvp[0], v = kvp[1];
1064
- var serverVal = serverState[v];
1065
- if (!_isUndefined(serverVal) && !_.isNull(serverVal)) newState[k] = serverState[v];
1066
- });
1067
-
1068
- if (serverState.order) {
1069
- newState.order = _invert(queryParams.directions)[serverState.order] * 1;
1070
- }
1071
-
1072
- return newState;
1073
- }
1074
- },
1075
-
1076
- /**
1077
- Parse server response for an array of model objects.
1078
-
1079
- This default implementation first checks whether the response has any
1080
- state object as documented in #parse. If it exists, the array of model
1081
- objects is assumed to be the second element, otherwise the entire
1082
- response is returned directly.
1083
-
1084
- @param {Object} resp The deserialized response data from the server.
1085
- @param {Object} [options] The options passed through from the
1086
- `parse`. (backbone >= 0.9.10 only)
1087
-
1088
- @return {Array.<Object>} An array of model objects
1089
- */
1090
- parseRecords: function (resp, options) {
1091
- if (resp && resp.length === 2 && _isObject(resp[0]) && _isArray(resp[1])) {
1092
- return resp[1];
1093
- }
1094
-
1095
- return resp;
1096
- },
1097
-
1098
- /**
1099
- Fetch a page from the server in server mode, or all the pages in client
1100
- mode. Under infinite mode, the current page is refetched by default and
1101
- then reset.
1102
-
1103
- The query string is constructed by translating the current pagination
1104
- state to your server API query parameter using #queryParams. The current
1105
- page will reset after fetch.
1106
-
1107
- @param {Object} [options] Accepts all
1108
- [Backbone.Collection#fetch](http://backbonejs.org/#Collection-fetch)
1109
- options.
1110
-
1111
- @return {XMLHttpRequest}
1112
- */
1113
- fetch: function (options) {
1114
-
1115
- options = options || {};
1116
-
1117
- var state = this._checkState(this.state);
1118
-
1119
- var mode = this.mode;
1120
-
1121
- if (mode == "infinite" && !options.url) {
1122
- options.url = this.links[state.currentPage];
1123
- }
1124
-
1125
- var data = options.data || {};
1126
-
1127
- // dedup query params
1128
- var url = _result(options, "url") || _result(this, "url") || '';
1129
- var qsi = url.indexOf('?');
1130
- if (qsi != -1) {
1131
- _extend(data, queryStringToParams(url.slice(qsi + 1)));
1132
- url = url.slice(0, qsi);
1133
- }
1134
-
1135
- options.url = url;
1136
- options.data = data;
1137
-
1138
- // map params except directions
1139
- var queryParams = this.mode == "client" ?
1140
- _pick(this.queryParams, "sortKey", "order") :
1141
- _omit(_pick(this.queryParams, _keys(PageableProto.queryParams)),
1142
- "directions");
1143
-
1144
- var i, kvp, k, v, kvps = _pairs(queryParams), thisCopy = _clone(this);
1145
- for (i = 0; i < kvps.length; i++) {
1146
- kvp = kvps[i], k = kvp[0], v = kvp[1];
1147
- v = _isFunction(v) ? v.call(thisCopy) : v;
1148
- if (state[k] != null && v != null) {
1149
- data[v] = state[k];
1150
- }
1151
- }
1152
-
1153
- // fix up sorting parameters
1154
- if (state.sortKey && state.order) {
1155
- data[queryParams.order] = this.queryParams.directions[state.order + ""];
1156
- }
1157
- else if (!state.sortKey) delete data[queryParams.order];
1158
-
1159
- // map extra query parameters
1160
- var extraKvps = _pairs(_omit(this.queryParams,
1161
- _keys(PageableProto.queryParams)));
1162
- for (i = 0; i < extraKvps.length; i++) {
1163
- kvp = extraKvps[i];
1164
- v = kvp[1];
1165
- v = _isFunction(v) ? v.call(thisCopy) : v;
1166
- if (v != null) data[kvp[0]] = v;
1167
- }
1168
-
1169
- if (mode != "server") {
1170
- var self = this, fullCol = this.fullCollection;
1171
- var success = options.success;
1172
- options.success = function (col, resp, opts) {
1173
-
1174
- // make sure the caller's intent is obeyed
1175
- opts = opts || {};
1176
- if (_isUndefined(options.silent)) delete opts.silent;
1177
- else opts.silent = options.silent;
1178
-
1179
- var models = col.models;
1180
- if (mode == "client") fullCol.reset(models, opts);
1181
- else {
1182
- fullCol.add(models, _extend({at: fullCol.length},
1183
- _extend(opts, {parse: false})));
1184
- self.trigger("reset", self, opts);
1185
- }
1186
-
1187
- if (success) success(col, resp, opts);
1188
- };
1189
-
1190
- // silent the first reset from backbone
1191
- return BBColProto.fetch.call(this, _extend({}, options, {silent: true}));
1192
- }
1193
-
1194
- return BBColProto.fetch.call(this, options);
1195
- },
1196
-
1197
- /**
1198
- Convenient method for making a `comparator` sorted by a model attribute
1199
- identified by `sortKey` and ordered by `order`.
1200
-
1201
- Like a Backbone.Collection, a Backbone.PageableCollection will maintain
1202
- the __current page__ in sorted order on the client side if a `comparator`
1203
- is attached to it. If the collection is in client mode, you can attach a
1204
- comparator to #fullCollection to have all the pages reflect the global
1205
- sorting order by specifying an option `full` to `true`. You __must__ call
1206
- `sort` manually or #fullCollection.sort after calling this method to
1207
- force a resort.
1208
-
1209
- While you can use this method to sort the current page in server mode,
1210
- the sorting order may not reflect the global sorting order due to the
1211
- additions or removals of the records on the server since the last
1212
- fetch. If you want the most updated page in a global sorting order, it is
1213
- recommended that you set #state.sortKey and optionally #state.order, and
1214
- then call #fetch.
1215
-
1216
- @protected
1217
-
1218
- @param {string} [sortKey=this.state.sortKey] See `state.sortKey`.
1219
- @param {number} [order=this.state.order] See `state.order`.
1220
- @param {(function(Backbone.Model, string): Object) | string} [sortValue] See #setSorting.
1221
-
1222
- See [Backbone.Collection.comparator](http://backbonejs.org/#Collection-comparator).
1223
- */
1224
- _makeComparator: function (sortKey, order, sortValue) {
1225
- var state = this.state;
1226
-
1227
- sortKey = sortKey || state.sortKey;
1228
- order = order || state.order;
1229
-
1230
- if (!sortKey || !order) return;
1231
-
1232
- if (!sortValue) sortValue = function (model, attr) {
1233
- return model.get(attr);
1234
- };
1235
-
1236
- return function (left, right) {
1237
- var l = sortValue(left, sortKey), r = sortValue(right, sortKey), t;
1238
- if (order === 1) t = l, l = r, r = t;
1239
- if (l === r) return 0;
1240
- else if (l < r) return -1;
1241
- return 1;
1242
- };
1243
- },
1244
-
1245
- /**
1246
- Adjusts the sorting for this pageable collection.
1247
-
1248
- Given a `sortKey` and an `order`, sets `state.sortKey` and
1249
- `state.order`. A comparator can be applied on the client side to sort in
1250
- the order defined if `options.side` is `"client"`. By default the
1251
- comparator is applied to the #fullCollection. Set `options.full` to
1252
- `false` to apply a comparator to the current page under any mode. Setting
1253
- `sortKey` to `null` removes the comparator from both the current page and
1254
- the full collection.
1255
-
1256
- If a `sortValue` function is given, it will be passed the `(model,
1257
- sortKey)` arguments and is used to extract a value from the model during
1258
- comparison sorts. If `sortValue` is not given, `model.get(sortKey)` is
1259
- used for sorting.
1260
-
1261
- @chainable
1262
-
1263
- @param {string} sortKey See `state.sortKey`.
1264
- @param {number} [order=this.state.order] See `state.order`.
1265
- @param {Object} [options]
1266
- @param {"server"|"client"} [options.side] By default, `"client"` if
1267
- `mode` is `"client"`, `"server"` otherwise.
1268
- @param {boolean} [options.full=true]
1269
- @param {(function(Backbone.Model, string): Object) | string} [options.sortValue]
1270
- */
1271
- setSorting: function (sortKey, order, options) {
1272
-
1273
- var state = this.state;
1274
-
1275
- state.sortKey = sortKey;
1276
- state.order = order = order || state.order;
1277
-
1278
- var fullCollection = this.fullCollection;
1279
-
1280
- var delComp = false, delFullComp = false;
1281
-
1282
- if (!sortKey) delComp = delFullComp = true;
1283
-
1284
- var mode = this.mode;
1285
- options = _extend({side: mode == "client" ? mode : "server", full: true},
1286
- options);
1287
-
1288
- var comparator = this._makeComparator(sortKey, order, options.sortValue);
1289
-
1290
- var full = options.full, side = options.side;
1291
-
1292
- if (side == "client") {
1293
- if (full) {
1294
- if (fullCollection) fullCollection.comparator = comparator;
1295
- delComp = true;
1296
- }
1297
- else {
1298
- this.comparator = comparator;
1299
- delFullComp = true;
1300
- }
1301
- }
1302
- else if (side == "server" && !full) {
1303
- this.comparator = comparator;
1304
- }
1305
-
1306
- if (delComp) this.comparator = null;
1307
- if (delFullComp && fullCollection) fullCollection.comparator = null;
1308
-
1309
- return this;
1310
- }
1311
-
1312
- });
1313
-
1314
- var PageableProto = PageableCollection.prototype;
1315
-
1316
- return PageableCollection;
1317
-
1318
- }));