Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
beefproject
GitHub Repository: beefproject/beef
Path: blob/master/extensions/admin_ui/media/javascript/ux/PagingStore.js
1154 views
1
//
2
// Copyright (c) 2006-2025 Wade Alcorn - [email protected]
3
// Browser Exploitation Framework (BeEF) - https://beefproject.com
4
// See the file 'doc/COPYING' for copying permission
5
//
6
7
/*
8
* PagingStore for Ext 3.2 - v0.5
9
*/
10
Ext.ns('Ext.ux.data');
11
Ext.ux.data.PagingStore = Ext.extend(Ext.data.Store, {
12
add: function (records) {
13
records = [].concat(records);
14
if (records.length < 1) {
15
return;
16
}
17
for (var i = 0, len = records.length; i < len; i++) {
18
records[i].join(this);
19
}
20
var index = this.data.length;
21
this.data.addAll(records);
22
// *** add ***
23
if (this.allData) {
24
this.allData.addAll(records);
25
}
26
// *** end ***
27
if (this.snapshot) {
28
this.snapshot.addAll(records);
29
}
30
// *** add ***
31
this.totalLength += records.length;
32
// *** end ***
33
this.fireEvent('add', this, records, index);
34
},
35
remove: function (record) {
36
if (Ext.isArray(record)) {
37
Ext.each(record, function (r) {
38
this.remove(r);
39
}, this);
40
return;
41
}
42
// *** add ***
43
if (this != record.store) {
44
return;
45
}
46
record.join(null);
47
// *** end ***
48
var index = this.data.indexOf(record);
49
if (index > -1) {
50
// record.join(null);
51
this.data.removeAt(index);
52
}
53
if (this.pruneModifiedRecords) {
54
this.modified.remove(record);
55
}
56
// *** add ***
57
if (this.allData) {
58
this.allData.remove(record);
59
}
60
// *** end ***
61
if (this.snapshot) {
62
this.snapshot.remove(record);
63
}
64
// *** add ***
65
this.totalLength--;
66
// *** end ***
67
if (index > -1) {
68
this.fireEvent('remove', this, record, index);
69
}
70
},
71
removeAll: function (silent) {
72
// *** add ***
73
var items = [].concat((this.snapshot || this.allData || this.data).items);
74
// *** end ***
75
// var items = [];
76
// this.each(function (rec) {
77
// items.push(rec);
78
// });
79
this.clearData();
80
// if (this.snapshot) {
81
// this.snapshot.clear();
82
// }
83
if (this.pruneModifiedRecords) {
84
this.modified = [];
85
}
86
// *** add ***
87
this.totalLength = 0;
88
// *** end ***
89
if (silent !== true) {
90
this.fireEvent('clear', this, items);
91
}
92
},
93
insert: function (index, records) {
94
records = [].concat(records);
95
for (var i = 0, len = records.length; i < len; i++) {
96
this.data.insert(index, records[i]);
97
records[i].join(this);
98
}
99
// *** add ***
100
if (this.allData) {
101
this.allData.addAll(records);
102
}
103
// *** end ***
104
if (this.snapshot) {
105
this.snapshot.addAll(records);
106
}
107
// *** add ***
108
this.totalLength += records.length;
109
// *** end ***
110
this.fireEvent('add', this, records, index);
111
},
112
getById: function (id) {
113
// *** add ***
114
return (this.snapshot || this.allData || this.data).key(id);
115
// *** end ***
116
// return this.data.key(id);
117
},
118
clearData: function () {
119
// *** add ***
120
if (this.allData) {
121
this.data = this.allData;
122
delete this.allData;
123
}
124
if (this.snapshot) {
125
this.data = this.snapshot;
126
delete this.snapshot;
127
}
128
// *** end ***
129
this.data.each(function (rec) {
130
rec.join(null);
131
});
132
this.data.clear();
133
},
134
execute: function (action, rs, options, batch) {
135
if (!Ext.data.Api.isAction(action)) {
136
throw new Ext.data.Api.Error('execute', action);
137
}
138
options = Ext.applyIf(options || {}, {
139
params: {}
140
});
141
if (batch !== undefined) {
142
this.addToBatch(batch);
143
}
144
var doRequest = true;
145
if (action === 'read') {
146
doRequest = this.fireEvent('beforeload', this, options);
147
Ext.applyIf(options.params, this.baseParams);
148
}
149
else {
150
if (this.writer.listful === true && this.restful !== true) {
151
rs = (Ext.isArray(rs)) ? rs : [rs];
152
}
153
else if (Ext.isArray(rs) && rs.length == 1) {
154
rs = rs.shift();
155
}
156
if ((doRequest = this.fireEvent('beforewrite', this, action, rs, options)) !== false) {
157
this.writer.apply(options.params, this.baseParams, action, rs);
158
}
159
}
160
if (doRequest !== false) {
161
if (this.writer && this.proxy.url && !this.proxy.restful && !Ext.data.Api.hasUniqueUrl(this.proxy, action)) {
162
options.params.xaction = action;
163
}
164
// *** add ***
165
if (action === "read" && this.isPaging(Ext.apply({}, options.params))) {
166
(function () {
167
if (this.allData) {
168
this.data = this.allData;
169
delete this.allData;
170
}
171
this.applyPaging();
172
this.fireEvent("datachanged", this);
173
var r = [].concat(this.data.items);
174
this.fireEvent("load", this, r, options);
175
if (options.callback) {
176
options.callback.call(options.scope || this, r, options, true);
177
}
178
}).defer(1, this);
179
return true;
180
}
181
// *** end ***
182
this.proxy.request(Ext.data.Api.actions[action], rs, options.params, this.reader, this.createCallback(action, rs, batch), this, options);
183
}
184
return doRequest;
185
},
186
loadRecords: function (o, options, success) {
187
if (this.isDestroyed === true) {
188
return;
189
}
190
if (!o || success === false) {
191
if (success !== false) {
192
this.fireEvent('load', this, [], options);
193
}
194
if (options.callback) {
195
options.callback.call(options.scope || this, [], options, false, o);
196
}
197
return;
198
}
199
var r = o.records,
200
t = o.totalRecords || r.length;
201
if (!options || options.add !== true) {
202
if (this.pruneModifiedRecords) {
203
this.modified = [];
204
}
205
for (var i = 0, len = r.length; i < len; i++) {
206
r[i].join(this);
207
}
208
//if (this.snapshot) {
209
// this.data = this.snapshot;
210
// delete this.snapshot;
211
//}
212
this.clearData();
213
this.data.addAll(r);
214
this.totalLength = t;
215
this.applySort();
216
// *** add ***
217
if (!this.allData) {
218
this.applyPaging();
219
}
220
if (r.length > this.getCount()) {
221
r = [].concat(this.data.items);
222
}
223
// *** end ***
224
this.fireEvent('datachanged', this);
225
} else {
226
this.totalLength = Math.max(t, this.data.length + r.length);
227
this.add(r);
228
}
229
this.fireEvent('load', this, r, options);
230
if (options.callback) {
231
options.callback.call(options.scope || this, r, options, true);
232
}
233
},
234
loadData: function (o, append) {
235
// *** add ***
236
this.isPaging(Ext.apply({}, this.lastOptions ? this.lastOptions.params : null, this.baseParams));
237
// *** end ***
238
var r = this.reader.readRecords(o);
239
this.loadRecords(r, {
240
add: append
241
}, true);
242
},
243
getTotalCount: function () {
244
// *** add ***
245
if (this.allData) {
246
return this.allData.getCount();
247
}
248
// *** end ***
249
return this.totalLength || 0;
250
},
251
sortData: function () {
252
var sortInfo = this.hasMultiSort ? this.multiSortInfo : this.sortInfo,
253
direction = sortInfo.direction || "ASC",
254
sorters = sortInfo.sorters,
255
sortFns = [];
256
if (!this.hasMultiSort) {
257
sorters = [{
258
direction: direction,
259
field: sortInfo.field
260
}];
261
}
262
for (var i = 0, j = sorters.length; i < j; i++) {
263
sortFns.push(this.createSortFunction(sorters[i].field, sorters[i].direction));
264
}
265
if (!sortFns.length) {
266
return;
267
}
268
var directionModifier = direction.toUpperCase() == "DESC" ? -1 : 1;
269
var fn = function (r1, r2) {
270
var result = sortFns[0].call(this, r1, r2);
271
if (sortFns.length > 1) {
272
for (var i = 1, j = sortFns.length; i < j; i++) {
273
result = result || sortFns[i].call(this, r1, r2);
274
}
275
}
276
return directionModifier * result;
277
};
278
// *** add ***
279
if (this.allData) {
280
this.data = this.allData;
281
delete this.allData;
282
}
283
// *** end ***
284
this.data.sort(direction, fn);
285
if (this.snapshot && this.snapshot != this.data) {
286
this.snapshot.sort(direction, fn);
287
}
288
// *** add ***
289
this.applyPaging();
290
// *** end ***
291
},
292
filterBy: function (fn, scope) {
293
// *** add ***
294
this.snapshot = this.snapshot || this.allData || this.data;
295
// *** end ***
296
// this.snapshot = this.snapshot || this.data;
297
this.data = this.queryBy(fn, scope || this);
298
// *** add ***
299
this.applyPaging();
300
// *** end ***
301
this.fireEvent('datachanged', this);
302
},
303
clearFilter: function (suppressEvent) {
304
if (this.isFiltered()) {
305
this.data = this.snapshot;
306
delete this.snapshot;
307
// *** add ***
308
delete this.allData;
309
this.applyPaging();
310
// *** end ***
311
if (suppressEvent !== true) {
312
this.fireEvent('datachanged', this);
313
}
314
}
315
},
316
isFiltered: function () {
317
// *** add ***
318
return !!this.snapshot && this.snapshot != (this.allData || this.data);
319
// *** end ***
320
// return !!this.snapshot && this.snapshot != this.data;
321
},
322
queryBy: function (fn, scope) {
323
// *** add ***
324
var data = this.snapshot || this.allData || this.data;
325
// *** end ***
326
// var data = this.snapshot || this.data;
327
return data.filterBy(fn, scope || this);
328
},
329
collect: function (dataIndex, allowNull, bypassFilter) {
330
// *** add ***
331
var d = (bypassFilter === true ? this.snapshot || this.allData || this.data : this.data).items;
332
// *** end ***
333
// var d = (bypassFilter === true && this.snapshot) ? this.snapshot.items : this.data.items;
334
var v, sv, r = [],
335
l = {};
336
for (var i = 0, len = d.length; i < len; i++) {
337
v = d[i].data[dataIndex];
338
sv = String(v);
339
if ((allowNull || !Ext.isEmpty(v)) && !l[sv]) {
340
l[sv] = true;
341
r[r.length] = v;
342
}
343
}
344
return r;
345
},
346
findInsertIndex : function(record){
347
this.suspendEvents();
348
var data = this.data.clone();
349
this.data.add(record);
350
this.applySort();
351
var index = this.data.indexOf(record);
352
this.data = data;
353
// *** add ***
354
this.totalLength--;
355
// *** end ***
356
this.resumeEvents();
357
return index;
358
},
359
// *** add ***
360
isPaging: function (params) {
361
var pn = this.paramNames,
362
start = params[pn.start],
363
limit = params[pn.limit];
364
if ((typeof start != 'number') || (typeof limit != 'number')) {
365
delete this.start;
366
delete this.limit;
367
this.lastParams = params;
368
return false;
369
}
370
this.start = start;
371
this.limit = limit;
372
delete params[pn.start];
373
delete params[pn.limit];
374
var lastParams = this.lastParams;
375
this.lastParams = params;
376
if (!this.proxy) {
377
return true;
378
}
379
if (!lastParams) {
380
return false;
381
}
382
for (var param in params) {
383
if (params.hasOwnProperty(param) && (params[param] !== lastParams[param])) {
384
return false;
385
}
386
}
387
for (param in lastParams) {
388
if (lastParams.hasOwnProperty(param) && (params[param] !== lastParams[param])) {
389
return false;
390
}
391
}
392
return true;
393
},
394
applyPaging: function () {
395
var start = this.start,
396
limit = this.limit;
397
if ((typeof start == 'number') && (typeof limit == 'number')) {
398
var allData = this.data,
399
data = new Ext.util.MixedCollection(allData.allowFunctions, allData.getKey);
400
data.items = allData.items.slice(start, start + limit);
401
data.keys = allData.keys.slice(start, start + limit);
402
var len = data.length = data.items.length;
403
var map = {};
404
for (var i = 0; i < len; i++) {
405
var item = data.items[i];
406
map[data.getKey(item)] = item;
407
}
408
data.map = map;
409
this.allData = allData;
410
this.data = data;
411
}
412
}
413
// *** end ***
414
});
415
416
Ext.ux.data.PagingDirectStore = Ext.extend(Ext.ux.data.PagingStore, {
417
constructor: Ext.data.DirectStore.prototype.constructor
418
});
419
Ext.reg('pagingdirectstore', Ext.ux.data.PagingDirectStore);
420
421
Ext.ux.data.PagingJsonStore = Ext.extend(Ext.ux.data.PagingStore, {
422
constructor: Ext.data.JsonStore.prototype.constructor
423
});
424
Ext.reg('pagingjsonstore', Ext.ux.data.PagingJsonStore);
425
426
Ext.ux.data.PagingXmlStore = Ext.extend(Ext.ux.data.PagingStore, {
427
constructor: Ext.data.XmlStore.prototype.constructor
428
});
429
Ext.reg('pagingxmlstore', Ext.ux.data.PagingXmlStore);
430
431
Ext.ux.data.PagingArrayStore = Ext.extend(Ext.ux.data.PagingStore, {
432
constructor: Ext.data.ArrayStore.prototype.constructor,
433
loadData: function (data, append) {
434
if (this.expandData === true) {
435
var r = [];
436
for (var i = 0, len = data.length; i < len; i++) {
437
r[r.length] = [data[i]];
438
}
439
data = r;
440
}
441
Ext.ux.data.PagingArrayStore.superclass.loadData.call(this, data, append);
442
}
443
});
444
Ext.reg('pagingarraystore', Ext.ux.data.PagingArrayStore);
445
446
Ext.ux.data.PagingSimpleStore = Ext.ux.data.PagingArrayStore;
447
Ext.reg('pagingsimplestore', Ext.ux.data.PagingSimpleStore);
448
449
Ext.ux.data.PagingGroupingStore = Ext.extend(Ext.ux.data.PagingStore, Ext.copyTo({}, Ext.data.GroupingStore.prototype, [
450
'constructor',
451
'remoteGroup',
452
'groupOnSort',
453
'groupDir',
454
'clearGrouping',
455
'groupBy',
456
'sort',
457
'applyGroupField',
458
'applyGrouping',
459
'getGroupState'
460
]));
461
Ext.reg('paginggroupingstore', Ext.ux.data.PagingGroupingStore);
462
463
Ext.ux.PagingToolbar = Ext.extend(Ext.PagingToolbar, {
464
onLoad: function (store, r, o) {
465
if (!this.rendered) {
466
this.dsLoaded = [store, r, o];
467
return;
468
}
469
var p = this.getParams();
470
this.cursor = (o.params && o.params[p.start]) ? o.params[p.start] : 0;
471
this.onChange();
472
// *** end ***
473
// var d = this.getPageData(),
474
// ap = d.activePage,
475
// ps = d.pages;
476
// this.afterTextItem.setText(String.format(this.afterPageText, d.pages));
477
// this.inputItem.setValue(ap);
478
// this.first.setDisabled(ap == 1);
479
// this.prev.setDisabled(ap == 1);
480
// this.next.setDisabled(ap == ps);
481
// this.last.setDisabled(ap == ps);
482
// this.refresh.enable();
483
// this.updateInfo();
484
// this.fireEvent('change', this, d);
485
},
486
onChange: function () {
487
// *** add ***
488
var t = this.store.getTotalCount(),
489
s = this.pageSize;
490
if (this.cursor >= t) {
491
this.cursor = Math.ceil((t + 1) / s) * s;
492
}
493
// *** end ***
494
var d = this.getPageData(),
495
ap = d.activePage,
496
ps = d.pages;
497
this.afterTextItem.setText(String.format(this.afterPageText, d.pages));
498
this.inputItem.setValue(ap);
499
this.first.setDisabled(ap == 1);
500
this.prev.setDisabled(ap == 1);
501
this.next.setDisabled(ap == ps);
502
this.last.setDisabled(ap == ps);
503
this.refresh.enable();
504
this.updateInfo();
505
this.fireEvent('change', this, d);
506
},
507
onClear: function () {
508
this.cursor = 0;
509
this.onChange();
510
},
511
doRefresh: function () {
512
// *** add ***
513
delete this.store.lastParams;
514
// *** end ***
515
this.doLoad(this.cursor);
516
},
517
bindStore: function (store, initial) {
518
var doLoad;
519
if (!initial && this.store) {
520
if (store !== this.store && this.store.autoDestroy) {
521
this.store.destroy();
522
} else {
523
this.store.un('beforeload', this.beforeLoad, this);
524
this.store.un('load', this.onLoad, this);
525
this.store.un('exception', this.onLoadError, this);
526
// *** add ***
527
this.store.un('datachanged', this.onChange, this);
528
this.store.un('add', this.onChange, this);
529
this.store.un('remove', this.onChange, this);
530
this.store.un('clear', this.onClear, this);
531
// *** end ***
532
}
533
if (!store) {
534
this.store = null;
535
}
536
}
537
if (store) {
538
store = Ext.StoreMgr.lookup(store);
539
store.on({
540
scope: this,
541
beforeload: this.beforeLoad,
542
load: this.onLoad,
543
exception: this.onLoadError,
544
// *** add ***
545
datachanged: this.onChange,
546
add: this.onChange,
547
remove: this.onChange,
548
clear: this.onClear
549
// *** end ***
550
});
551
doLoad = true;
552
}
553
this.store = store;
554
if (doLoad) {
555
this.onLoad(store, null, {});
556
}
557
}
558
});
559
Ext.reg('ux.paging', Ext.ux.PagingToolbar);
560
561