jquery.dgtable 0.5.59 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * jquery.dgtable 0.5.59
2
+ * jquery.dgtable 0.6.0
3
3
  * git://github.com/danielgindi/jquery.dgtable.git
4
4
  */
5
5
  'use strict';
@@ -15,7 +15,7 @@ var check = function (it) {
15
15
  };
16
16
 
17
17
  // https://github.com/zloirock/core-js/issues/86#issuecomment-115759028
18
- var global$a =
18
+ var global$b =
19
19
  // eslint-disable-next-line es/no-global-this -- safe
20
20
  check(typeof globalThis == 'object' && globalThis) ||
21
21
  check(typeof window == 'object' && window) ||
@@ -91,19 +91,19 @@ var FunctionPrototype$1 = Function.prototype;
91
91
  var call$3 = FunctionPrototype$1.call;
92
92
  var uncurryThisWithBind = NATIVE_BIND && FunctionPrototype$1.bind.bind(call$3, call$3);
93
93
 
94
- var functionUncurryThisRaw = function (fn) {
95
- return NATIVE_BIND ? uncurryThisWithBind(fn) : function () {
94
+ var functionUncurryThisRaw = NATIVE_BIND ? uncurryThisWithBind : function (fn) {
95
+ return function () {
96
96
  return call$3.apply(fn, arguments);
97
97
  };
98
98
  };
99
99
 
100
100
  var uncurryThisRaw$1 = functionUncurryThisRaw;
101
101
 
102
- var toString$3 = uncurryThisRaw$1({}.toString);
103
- var stringSlice = uncurryThisRaw$1(''.slice);
102
+ var toString$4 = uncurryThisRaw$1({}.toString);
103
+ var stringSlice$1 = uncurryThisRaw$1(''.slice);
104
104
 
105
105
  var classofRaw$2 = function (it) {
106
- return stringSlice(toString$3(it), 8, -1);
106
+ return stringSlice$1(toString$4(it), 8, -1);
107
107
  };
108
108
 
109
109
  var classofRaw$1 = classofRaw$2;
@@ -116,12 +116,12 @@ var functionUncurryThis = function (fn) {
116
116
  if (classofRaw$1(fn) === 'Function') return uncurryThisRaw(fn);
117
117
  };
118
118
 
119
- var uncurryThis$7 = functionUncurryThis;
119
+ var uncurryThis$8 = functionUncurryThis;
120
120
  var fails$7 = fails$a;
121
121
  var classof$2 = classofRaw$2;
122
122
 
123
123
  var $Object$3 = Object;
124
- var split = uncurryThis$7(''.split);
124
+ var split = uncurryThis$8(''.split);
125
125
 
126
126
  // fallback for non-array-like ES3 and non-enumerable old V8 strings
127
127
  var indexedObject = fails$7(function () {
@@ -173,47 +173,47 @@ var documentAll$1 = $documentAll$1.all;
173
173
 
174
174
  // `IsCallable` abstract operation
175
175
  // https://tc39.es/ecma262/#sec-iscallable
176
- var isCallable$b = $documentAll$1.IS_HTMLDDA ? function (argument) {
176
+ var isCallable$c = $documentAll$1.IS_HTMLDDA ? function (argument) {
177
177
  return typeof argument == 'function' || argument === documentAll$1;
178
178
  } : function (argument) {
179
179
  return typeof argument == 'function';
180
180
  };
181
181
 
182
- var isCallable$a = isCallable$b;
182
+ var isCallable$b = isCallable$c;
183
183
  var $documentAll = documentAll_1;
184
184
 
185
185
  var documentAll = $documentAll.all;
186
186
 
187
187
  var isObject$5 = $documentAll.IS_HTMLDDA ? function (it) {
188
- return typeof it == 'object' ? it !== null : isCallable$a(it) || it === documentAll;
188
+ return typeof it == 'object' ? it !== null : isCallable$b(it) || it === documentAll;
189
189
  } : function (it) {
190
- return typeof it == 'object' ? it !== null : isCallable$a(it);
190
+ return typeof it == 'object' ? it !== null : isCallable$b(it);
191
191
  };
192
192
 
193
- var global$9 = global$a;
194
- var isCallable$9 = isCallable$b;
193
+ var global$a = global$b;
194
+ var isCallable$a = isCallable$c;
195
195
 
196
196
  var aFunction = function (argument) {
197
- return isCallable$9(argument) ? argument : undefined;
197
+ return isCallable$a(argument) ? argument : undefined;
198
198
  };
199
199
 
200
200
  var getBuiltIn$3 = function (namespace, method) {
201
- return arguments.length < 2 ? aFunction(global$9[namespace]) : global$9[namespace] && global$9[namespace][method];
201
+ return arguments.length < 2 ? aFunction(global$a[namespace]) : global$a[namespace] && global$a[namespace][method];
202
202
  };
203
203
 
204
- var uncurryThis$6 = functionUncurryThis;
204
+ var uncurryThis$7 = functionUncurryThis;
205
205
 
206
- var objectIsPrototypeOf = uncurryThis$6({}.isPrototypeOf);
206
+ var objectIsPrototypeOf = uncurryThis$7({}.isPrototypeOf);
207
207
 
208
208
  var getBuiltIn$2 = getBuiltIn$3;
209
209
 
210
210
  var engineUserAgent = getBuiltIn$2('navigator', 'userAgent') || '';
211
211
 
212
- var global$8 = global$a;
212
+ var global$9 = global$b;
213
213
  var userAgent$3 = engineUserAgent;
214
214
 
215
- var process = global$8.process;
216
- var Deno = global$8.Deno;
215
+ var process = global$9.process;
216
+ var Deno = global$9.Deno;
217
217
  var versions = process && process.versions || Deno && Deno.version;
218
218
  var v8 = versions && versions.v8;
219
219
  var match, version;
@@ -254,15 +254,15 @@ var symbolConstructorDetection = !!Object.getOwnPropertySymbols && !fails$6(func
254
254
 
255
255
  /* eslint-disable es/no-symbol -- required for testing */
256
256
 
257
- var NATIVE_SYMBOL$1 = symbolConstructorDetection;
257
+ var NATIVE_SYMBOL$2 = symbolConstructorDetection;
258
258
 
259
- var useSymbolAsUid = NATIVE_SYMBOL$1
259
+ var useSymbolAsUid = NATIVE_SYMBOL$2
260
260
  && !Symbol.sham
261
261
  && typeof Symbol.iterator == 'symbol';
262
262
 
263
263
  var getBuiltIn$1 = getBuiltIn$3;
264
- var isCallable$8 = isCallable$b;
265
- var isPrototypeOf = objectIsPrototypeOf;
264
+ var isCallable$9 = isCallable$c;
265
+ var isPrototypeOf$1 = objectIsPrototypeOf;
266
266
  var USE_SYMBOL_AS_UID$1 = useSymbolAsUid;
267
267
 
268
268
  var $Object$2 = Object;
@@ -271,7 +271,7 @@ var isSymbol$2 = USE_SYMBOL_AS_UID$1 ? function (it) {
271
271
  return typeof it == 'symbol';
272
272
  } : function (it) {
273
273
  var $Symbol = getBuiltIn$1('Symbol');
274
- return isCallable$8($Symbol) && isPrototypeOf($Symbol.prototype, $Object$2(it));
274
+ return isCallable$9($Symbol) && isPrototypeOf$1($Symbol.prototype, $Object$2(it));
275
275
  };
276
276
 
277
277
  var $String$2 = String;
@@ -284,14 +284,14 @@ var tryToString$2 = function (argument) {
284
284
  }
285
285
  };
286
286
 
287
- var isCallable$7 = isCallable$b;
287
+ var isCallable$8 = isCallable$c;
288
288
  var tryToString$1 = tryToString$2;
289
289
 
290
290
  var $TypeError$5 = TypeError;
291
291
 
292
292
  // `Assert: IsCallable(argument) is true`
293
293
  var aCallable$2 = function (argument) {
294
- if (isCallable$7(argument)) return argument;
294
+ if (isCallable$8(argument)) return argument;
295
295
  throw $TypeError$5(tryToString$1(argument) + ' is not a function');
296
296
  };
297
297
 
@@ -306,7 +306,7 @@ var getMethod$1 = function (V, P) {
306
306
  };
307
307
 
308
308
  var call$2 = functionCall;
309
- var isCallable$6 = isCallable$b;
309
+ var isCallable$7 = isCallable$c;
310
310
  var isObject$4 = isObject$5;
311
311
 
312
312
  var $TypeError$4 = TypeError;
@@ -315,32 +315,32 @@ var $TypeError$4 = TypeError;
315
315
  // https://tc39.es/ecma262/#sec-ordinarytoprimitive
316
316
  var ordinaryToPrimitive$1 = function (input, pref) {
317
317
  var fn, val;
318
- if (pref === 'string' && isCallable$6(fn = input.toString) && !isObject$4(val = call$2(fn, input))) return val;
319
- if (isCallable$6(fn = input.valueOf) && !isObject$4(val = call$2(fn, input))) return val;
320
- if (pref !== 'string' && isCallable$6(fn = input.toString) && !isObject$4(val = call$2(fn, input))) return val;
318
+ if (pref === 'string' && isCallable$7(fn = input.toString) && !isObject$4(val = call$2(fn, input))) return val;
319
+ if (isCallable$7(fn = input.valueOf) && !isObject$4(val = call$2(fn, input))) return val;
320
+ if (pref !== 'string' && isCallable$7(fn = input.toString) && !isObject$4(val = call$2(fn, input))) return val;
321
321
  throw $TypeError$4("Can't convert object to primitive value");
322
322
  };
323
323
 
324
324
  var shared$3 = {exports: {}};
325
325
 
326
- var global$7 = global$a;
326
+ var global$8 = global$b;
327
327
 
328
328
  // eslint-disable-next-line es/no-object-defineproperty -- safe
329
- var defineProperty$1 = Object.defineProperty;
329
+ var defineProperty$2 = Object.defineProperty;
330
330
 
331
331
  var defineGlobalProperty$3 = function (key, value) {
332
332
  try {
333
- defineProperty$1(global$7, key, { value: value, configurable: true, writable: true });
333
+ defineProperty$2(global$8, key, { value: value, configurable: true, writable: true });
334
334
  } catch (error) {
335
- global$7[key] = value;
335
+ global$8[key] = value;
336
336
  } return value;
337
337
  };
338
338
 
339
- var global$6 = global$a;
339
+ var global$7 = global$b;
340
340
  var defineGlobalProperty$2 = defineGlobalProperty$3;
341
341
 
342
342
  var SHARED = '__core-js_shared__';
343
- var store$3 = global$6[SHARED] || defineGlobalProperty$2(SHARED, {});
343
+ var store$3 = global$7[SHARED] || defineGlobalProperty$2(SHARED, {});
344
344
 
345
345
  var sharedStore = store$3;
346
346
 
@@ -349,10 +349,10 @@ var store$2 = sharedStore;
349
349
  (shared$3.exports = function (key, value) {
350
350
  return store$2[key] || (store$2[key] = value !== undefined ? value : {});
351
351
  })('versions', []).push({
352
- version: '3.25.5',
352
+ version: '3.26.0',
353
353
  mode: 'global',
354
354
  copyright: '© 2014-2022 Denis Pushkarev (zloirock.ru)',
355
- license: 'https://github.com/zloirock/core-js/blob/v3.25.5/LICENSE',
355
+ license: 'https://github.com/zloirock/core-js/blob/v3.26.0/LICENSE',
356
356
  source: 'https://github.com/zloirock/core-js'
357
357
  });
358
358
 
@@ -366,44 +366,44 @@ var toObject$2 = function (argument) {
366
366
  return $Object$1(requireObjectCoercible(argument));
367
367
  };
368
368
 
369
- var uncurryThis$5 = functionUncurryThis;
369
+ var uncurryThis$6 = functionUncurryThis;
370
370
  var toObject$1 = toObject$2;
371
371
 
372
- var hasOwnProperty$1 = uncurryThis$5({}.hasOwnProperty);
372
+ var hasOwnProperty$2 = uncurryThis$6({}.hasOwnProperty);
373
373
 
374
374
  // `HasOwnProperty` abstract operation
375
375
  // https://tc39.es/ecma262/#sec-hasownproperty
376
376
  // eslint-disable-next-line es/no-object-hasown -- safe
377
377
  var hasOwnProperty_1 = Object.hasOwn || function hasOwn(it, key) {
378
- return hasOwnProperty$1(toObject$1(it), key);
378
+ return hasOwnProperty$2(toObject$1(it), key);
379
379
  };
380
380
 
381
- var uncurryThis$4 = functionUncurryThis;
381
+ var uncurryThis$5 = functionUncurryThis;
382
382
 
383
383
  var id = 0;
384
384
  var postfix = Math.random();
385
- var toString$2 = uncurryThis$4(1.0.toString);
385
+ var toString$3 = uncurryThis$5(1.0.toString);
386
386
 
387
387
  var uid$2 = function (key) {
388
- return 'Symbol(' + (key === undefined ? '' : key) + ')_' + toString$2(++id + postfix, 36);
388
+ return 'Symbol(' + (key === undefined ? '' : key) + ')_' + toString$3(++id + postfix, 36);
389
389
  };
390
390
 
391
- var global$5 = global$a;
391
+ var global$6 = global$b;
392
392
  var shared$2 = shared$3.exports;
393
- var hasOwn$6 = hasOwnProperty_1;
393
+ var hasOwn$7 = hasOwnProperty_1;
394
394
  var uid$1 = uid$2;
395
- var NATIVE_SYMBOL = symbolConstructorDetection;
395
+ var NATIVE_SYMBOL$1 = symbolConstructorDetection;
396
396
  var USE_SYMBOL_AS_UID = useSymbolAsUid;
397
397
 
398
398
  var WellKnownSymbolsStore = shared$2('wks');
399
- var Symbol$1 = global$5.Symbol;
399
+ var Symbol$1 = global$6.Symbol;
400
400
  var symbolFor = Symbol$1 && Symbol$1['for'];
401
401
  var createWellKnownSymbol = USE_SYMBOL_AS_UID ? Symbol$1 : Symbol$1 && Symbol$1.withoutSetter || uid$1;
402
402
 
403
403
  var wellKnownSymbol$3 = function (name) {
404
- if (!hasOwn$6(WellKnownSymbolsStore, name) || !(NATIVE_SYMBOL || typeof WellKnownSymbolsStore[name] == 'string')) {
404
+ if (!hasOwn$7(WellKnownSymbolsStore, name) || !(NATIVE_SYMBOL$1 || typeof WellKnownSymbolsStore[name] == 'string')) {
405
405
  var description = 'Symbol.' + name;
406
- if (NATIVE_SYMBOL && hasOwn$6(Symbol$1, name)) {
406
+ if (NATIVE_SYMBOL$1 && hasOwn$7(Symbol$1, name)) {
407
407
  WellKnownSymbolsStore[name] = Symbol$1[name];
408
408
  } else if (USE_SYMBOL_AS_UID && symbolFor) {
409
409
  WellKnownSymbolsStore[name] = symbolFor(description);
@@ -449,10 +449,10 @@ var toPropertyKey$3 = function (argument) {
449
449
  return isSymbol(key) ? key : key + '';
450
450
  };
451
451
 
452
- var global$4 = global$a;
452
+ var global$5 = global$b;
453
453
  var isObject$2 = isObject$5;
454
454
 
455
- var document$1 = global$4.document;
455
+ var document$1 = global$5.document;
456
456
  // typeof document.createElement is 'object' in old IE
457
457
  var EXISTS$1 = isObject$2(document$1) && isObject$2(document$1.createElement);
458
458
 
@@ -460,25 +460,25 @@ var documentCreateElement = function (it) {
460
460
  return EXISTS$1 ? document$1.createElement(it) : {};
461
461
  };
462
462
 
463
- var DESCRIPTORS$6 = descriptors;
463
+ var DESCRIPTORS$7 = descriptors;
464
464
  var fails$5 = fails$a;
465
465
  var createElement$1 = documentCreateElement;
466
466
 
467
467
  // Thanks to IE8 for its funny defineProperty
468
- var ie8DomDefine = !DESCRIPTORS$6 && !fails$5(function () {
468
+ var ie8DomDefine = !DESCRIPTORS$7 && !fails$5(function () {
469
469
  // eslint-disable-next-line es/no-object-defineproperty -- required for testing
470
470
  return Object.defineProperty(createElement$1('div'), 'a', {
471
471
  get: function () { return 7; }
472
472
  }).a != 7;
473
473
  });
474
474
 
475
- var DESCRIPTORS$5 = descriptors;
475
+ var DESCRIPTORS$6 = descriptors;
476
476
  var call = functionCall;
477
477
  var propertyIsEnumerableModule = objectPropertyIsEnumerable;
478
478
  var createPropertyDescriptor$2 = createPropertyDescriptor$3;
479
479
  var toIndexedObject$2 = toIndexedObject$3;
480
480
  var toPropertyKey$2 = toPropertyKey$3;
481
- var hasOwn$5 = hasOwnProperty_1;
481
+ var hasOwn$6 = hasOwnProperty_1;
482
482
  var IE8_DOM_DEFINE$1 = ie8DomDefine;
483
483
 
484
484
  // eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe
@@ -486,23 +486,23 @@ var $getOwnPropertyDescriptor$1 = Object.getOwnPropertyDescriptor;
486
486
 
487
487
  // `Object.getOwnPropertyDescriptor` method
488
488
  // https://tc39.es/ecma262/#sec-object.getownpropertydescriptor
489
- objectGetOwnPropertyDescriptor.f = DESCRIPTORS$5 ? $getOwnPropertyDescriptor$1 : function getOwnPropertyDescriptor(O, P) {
489
+ objectGetOwnPropertyDescriptor.f = DESCRIPTORS$6 ? $getOwnPropertyDescriptor$1 : function getOwnPropertyDescriptor(O, P) {
490
490
  O = toIndexedObject$2(O);
491
491
  P = toPropertyKey$2(P);
492
492
  if (IE8_DOM_DEFINE$1) try {
493
493
  return $getOwnPropertyDescriptor$1(O, P);
494
494
  } catch (error) { /* empty */ }
495
- if (hasOwn$5(O, P)) return createPropertyDescriptor$2(!call(propertyIsEnumerableModule.f, O, P), O[P]);
495
+ if (hasOwn$6(O, P)) return createPropertyDescriptor$2(!call(propertyIsEnumerableModule.f, O, P), O[P]);
496
496
  };
497
497
 
498
498
  var objectDefineProperty = {};
499
499
 
500
- var DESCRIPTORS$4 = descriptors;
500
+ var DESCRIPTORS$5 = descriptors;
501
501
  var fails$4 = fails$a;
502
502
 
503
503
  // V8 ~ Chrome 36-
504
504
  // https://bugs.chromium.org/p/v8/issues/detail?id=3334
505
- var v8PrototypeDefineBug = DESCRIPTORS$4 && fails$4(function () {
505
+ var v8PrototypeDefineBug = DESCRIPTORS$5 && fails$4(function () {
506
506
  // eslint-disable-next-line es/no-object-defineproperty -- required for testing
507
507
  return Object.defineProperty(function () { /* empty */ }, 'prototype', {
508
508
  value: 42,
@@ -521,7 +521,7 @@ var anObject$2 = function (argument) {
521
521
  throw $TypeError$2($String$1(argument) + ' is not an object');
522
522
  };
523
523
 
524
- var DESCRIPTORS$3 = descriptors;
524
+ var DESCRIPTORS$4 = descriptors;
525
525
  var IE8_DOM_DEFINE = ie8DomDefine;
526
526
  var V8_PROTOTYPE_DEFINE_BUG = v8PrototypeDefineBug;
527
527
  var anObject$1 = anObject$2;
@@ -538,7 +538,7 @@ var WRITABLE = 'writable';
538
538
 
539
539
  // `Object.defineProperty` method
540
540
  // https://tc39.es/ecma262/#sec-object.defineproperty
541
- objectDefineProperty.f = DESCRIPTORS$3 ? V8_PROTOTYPE_DEFINE_BUG ? function defineProperty(O, P, Attributes) {
541
+ objectDefineProperty.f = DESCRIPTORS$4 ? V8_PROTOTYPE_DEFINE_BUG ? function defineProperty(O, P, Attributes) {
542
542
  anObject$1(O);
543
543
  P = toPropertyKey$1(P);
544
544
  anObject$1(Attributes);
@@ -565,11 +565,11 @@ objectDefineProperty.f = DESCRIPTORS$3 ? V8_PROTOTYPE_DEFINE_BUG ? function defi
565
565
  return O;
566
566
  };
567
567
 
568
- var DESCRIPTORS$2 = descriptors;
568
+ var DESCRIPTORS$3 = descriptors;
569
569
  var definePropertyModule$3 = objectDefineProperty;
570
570
  var createPropertyDescriptor$1 = createPropertyDescriptor$3;
571
571
 
572
- var createNonEnumerableProperty$2 = DESCRIPTORS$2 ? function (object, key, value) {
572
+ var createNonEnumerableProperty$2 = DESCRIPTORS$3 ? function (object, key, value) {
573
573
  return definePropertyModule$3.f(object, key, createPropertyDescriptor$1(1, value));
574
574
  } : function (object, key, value) {
575
575
  object[key] = value;
@@ -578,17 +578,17 @@ var createNonEnumerableProperty$2 = DESCRIPTORS$2 ? function (object, key, value
578
578
 
579
579
  var makeBuiltIn$2 = {exports: {}};
580
580
 
581
- var DESCRIPTORS$1 = descriptors;
582
- var hasOwn$4 = hasOwnProperty_1;
581
+ var DESCRIPTORS$2 = descriptors;
582
+ var hasOwn$5 = hasOwnProperty_1;
583
583
 
584
584
  var FunctionPrototype = Function.prototype;
585
585
  // eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe
586
- var getDescriptor = DESCRIPTORS$1 && Object.getOwnPropertyDescriptor;
586
+ var getDescriptor = DESCRIPTORS$2 && Object.getOwnPropertyDescriptor;
587
587
 
588
- var EXISTS = hasOwn$4(FunctionPrototype, 'name');
588
+ var EXISTS = hasOwn$5(FunctionPrototype, 'name');
589
589
  // additional protection from minified / mangled / dropped function names
590
590
  var PROPER = EXISTS && (function something() { /* empty */ }).name === 'something';
591
- var CONFIGURABLE = EXISTS && (!DESCRIPTORS$1 || (DESCRIPTORS$1 && getDescriptor(FunctionPrototype, 'name').configurable));
591
+ var CONFIGURABLE = EXISTS && (!DESCRIPTORS$2 || (DESCRIPTORS$2 && getDescriptor(FunctionPrototype, 'name').configurable));
592
592
 
593
593
  var functionName = {
594
594
  EXISTS: EXISTS,
@@ -596,14 +596,14 @@ var functionName = {
596
596
  CONFIGURABLE: CONFIGURABLE
597
597
  };
598
598
 
599
- var uncurryThis$3 = functionUncurryThis;
600
- var isCallable$5 = isCallable$b;
599
+ var uncurryThis$4 = functionUncurryThis;
600
+ var isCallable$6 = isCallable$c;
601
601
  var store$1 = sharedStore;
602
602
 
603
- var functionToString = uncurryThis$3(Function.toString);
603
+ var functionToString = uncurryThis$4(Function.toString);
604
604
 
605
605
  // this helper broken in `core-js@3.4.1-3.4.4`, so we can't use `shared` helper
606
- if (!isCallable$5(store$1.inspectSource)) {
606
+ if (!isCallable$6(store$1.inspectSource)) {
607
607
  store$1.inspectSource = function (it) {
608
608
  return functionToString(it);
609
609
  };
@@ -611,12 +611,12 @@ if (!isCallable$5(store$1.inspectSource)) {
611
611
 
612
612
  var inspectSource$1 = store$1.inspectSource;
613
613
 
614
- var global$3 = global$a;
615
- var isCallable$4 = isCallable$b;
614
+ var global$4 = global$b;
615
+ var isCallable$5 = isCallable$c;
616
616
 
617
- var WeakMap$1 = global$3.WeakMap;
617
+ var WeakMap$1 = global$4.WeakMap;
618
618
 
619
- var weakMapBasicDetection = isCallable$4(WeakMap$1) && /native code/.test(String(WeakMap$1));
619
+ var weakMapBasicDetection = isCallable$5(WeakMap$1) && /native code/.test(String(WeakMap$1));
620
620
 
621
621
  var shared$1 = shared$3.exports;
622
622
  var uid = uid$2;
@@ -630,17 +630,17 @@ var sharedKey$1 = function (key) {
630
630
  var hiddenKeys$3 = {};
631
631
 
632
632
  var NATIVE_WEAK_MAP = weakMapBasicDetection;
633
- var global$2 = global$a;
633
+ var global$3 = global$b;
634
634
  var isObject = isObject$5;
635
635
  var createNonEnumerableProperty$1 = createNonEnumerableProperty$2;
636
- var hasOwn$3 = hasOwnProperty_1;
636
+ var hasOwn$4 = hasOwnProperty_1;
637
637
  var shared = sharedStore;
638
638
  var sharedKey = sharedKey$1;
639
639
  var hiddenKeys$2 = hiddenKeys$3;
640
640
 
641
641
  var OBJECT_ALREADY_INITIALIZED = 'Object already initialized';
642
- var TypeError$1 = global$2.TypeError;
643
- var WeakMap = global$2.WeakMap;
642
+ var TypeError$1 = global$3.TypeError;
643
+ var WeakMap = global$3.WeakMap;
644
644
  var set, get, has;
645
645
 
646
646
  var enforce = function (it) {
@@ -679,16 +679,16 @@ if (NATIVE_WEAK_MAP || shared.state) {
679
679
  var STATE = sharedKey('state');
680
680
  hiddenKeys$2[STATE] = true;
681
681
  set = function (it, metadata) {
682
- if (hasOwn$3(it, STATE)) throw TypeError$1(OBJECT_ALREADY_INITIALIZED);
682
+ if (hasOwn$4(it, STATE)) throw TypeError$1(OBJECT_ALREADY_INITIALIZED);
683
683
  metadata.facade = it;
684
684
  createNonEnumerableProperty$1(it, STATE, metadata);
685
685
  return metadata;
686
686
  };
687
687
  get = function (it) {
688
- return hasOwn$3(it, STATE) ? it[STATE] : {};
688
+ return hasOwn$4(it, STATE) ? it[STATE] : {};
689
689
  };
690
690
  has = function (it) {
691
- return hasOwn$3(it, STATE);
691
+ return hasOwn$4(it, STATE);
692
692
  };
693
693
  }
694
694
 
@@ -701,9 +701,9 @@ var internalState = {
701
701
  };
702
702
 
703
703
  var fails$3 = fails$a;
704
- var isCallable$3 = isCallable$b;
705
- var hasOwn$2 = hasOwnProperty_1;
706
- var DESCRIPTORS = descriptors;
704
+ var isCallable$4 = isCallable$c;
705
+ var hasOwn$3 = hasOwnProperty_1;
706
+ var DESCRIPTORS$1 = descriptors;
707
707
  var CONFIGURABLE_FUNCTION_NAME = functionName.CONFIGURABLE;
708
708
  var inspectSource = inspectSource$1;
709
709
  var InternalStateModule = internalState;
@@ -711,10 +711,10 @@ var InternalStateModule = internalState;
711
711
  var enforceInternalState = InternalStateModule.enforce;
712
712
  var getInternalState = InternalStateModule.get;
713
713
  // eslint-disable-next-line es/no-object-defineproperty -- safe
714
- var defineProperty = Object.defineProperty;
714
+ var defineProperty$1 = Object.defineProperty;
715
715
 
716
- var CONFIGURABLE_LENGTH = DESCRIPTORS && !fails$3(function () {
717
- return defineProperty(function () { /* empty */ }, 'length', { value: 8 }).length !== 8;
716
+ var CONFIGURABLE_LENGTH = DESCRIPTORS$1 && !fails$3(function () {
717
+ return defineProperty$1(function () { /* empty */ }, 'length', { value: 8 }).length !== 8;
718
718
  });
719
719
 
720
720
  var TEMPLATE = String(String).split('String');
@@ -725,21 +725,21 @@ var makeBuiltIn$1 = makeBuiltIn$2.exports = function (value, name, options) {
725
725
  }
726
726
  if (options && options.getter) name = 'get ' + name;
727
727
  if (options && options.setter) name = 'set ' + name;
728
- if (!hasOwn$2(value, 'name') || (CONFIGURABLE_FUNCTION_NAME && value.name !== name)) {
729
- if (DESCRIPTORS) defineProperty(value, 'name', { value: name, configurable: true });
728
+ if (!hasOwn$3(value, 'name') || (CONFIGURABLE_FUNCTION_NAME && value.name !== name)) {
729
+ if (DESCRIPTORS$1) defineProperty$1(value, 'name', { value: name, configurable: true });
730
730
  else value.name = name;
731
731
  }
732
- if (CONFIGURABLE_LENGTH && options && hasOwn$2(options, 'arity') && value.length !== options.arity) {
733
- defineProperty(value, 'length', { value: options.arity });
732
+ if (CONFIGURABLE_LENGTH && options && hasOwn$3(options, 'arity') && value.length !== options.arity) {
733
+ defineProperty$1(value, 'length', { value: options.arity });
734
734
  }
735
735
  try {
736
- if (options && hasOwn$2(options, 'constructor') && options.constructor) {
737
- if (DESCRIPTORS) defineProperty(value, 'prototype', { writable: false });
736
+ if (options && hasOwn$3(options, 'constructor') && options.constructor) {
737
+ if (DESCRIPTORS$1) defineProperty$1(value, 'prototype', { writable: false });
738
738
  // in V8 ~ Chrome 53, prototypes of some methods, like `Array.prototype.values`, are non-writable
739
739
  } else if (value.prototype) value.prototype = undefined;
740
740
  } catch (error) { /* empty */ }
741
741
  var state = enforceInternalState(value);
742
- if (!hasOwn$2(state, 'source')) {
742
+ if (!hasOwn$3(state, 'source')) {
743
743
  state.source = TEMPLATE.join(typeof name == 'string' ? name : '');
744
744
  } return value;
745
745
  };
@@ -747,10 +747,10 @@ var makeBuiltIn$1 = makeBuiltIn$2.exports = function (value, name, options) {
747
747
  // add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative
748
748
  // eslint-disable-next-line no-extend-native -- required
749
749
  Function.prototype.toString = makeBuiltIn$1(function toString() {
750
- return isCallable$3(this) && getInternalState(this).source || inspectSource(this);
750
+ return isCallable$4(this) && getInternalState(this).source || inspectSource(this);
751
751
  }, 'toString');
752
752
 
753
- var isCallable$2 = isCallable$b;
753
+ var isCallable$3 = isCallable$c;
754
754
  var definePropertyModule$2 = objectDefineProperty;
755
755
  var makeBuiltIn = makeBuiltIn$2.exports;
756
756
  var defineGlobalProperty$1 = defineGlobalProperty$3;
@@ -759,7 +759,7 @@ var defineBuiltIn$1 = function (O, key, value, options) {
759
759
  if (!options) options = {};
760
760
  var simple = options.enumerable;
761
761
  var name = options.name !== undefined ? options.name : key;
762
- if (isCallable$2(value)) makeBuiltIn(value, name, options);
762
+ if (isCallable$3(value)) makeBuiltIn(value, name, options);
763
763
  if (options.global) {
764
764
  if (simple) O[key] = value;
765
765
  else defineGlobalProperty$1(key, value);
@@ -865,22 +865,22 @@ var arrayIncludes = {
865
865
  indexOf: createMethod(false)
866
866
  };
867
867
 
868
- var uncurryThis$2 = functionUncurryThis;
869
- var hasOwn$1 = hasOwnProperty_1;
868
+ var uncurryThis$3 = functionUncurryThis;
869
+ var hasOwn$2 = hasOwnProperty_1;
870
870
  var toIndexedObject = toIndexedObject$3;
871
871
  var indexOf$1 = arrayIncludes.indexOf;
872
872
  var hiddenKeys$1 = hiddenKeys$3;
873
873
 
874
- var push$1 = uncurryThis$2([].push);
874
+ var push$1 = uncurryThis$3([].push);
875
875
 
876
876
  var objectKeysInternal = function (object, names) {
877
877
  var O = toIndexedObject(object);
878
878
  var i = 0;
879
879
  var result = [];
880
880
  var key;
881
- for (key in O) !hasOwn$1(hiddenKeys$1, key) && hasOwn$1(O, key) && push$1(result, key);
881
+ for (key in O) !hasOwn$2(hiddenKeys$1, key) && hasOwn$2(O, key) && push$1(result, key);
882
882
  // Don't enum bug & hidden keys
883
- while (names.length > i) if (hasOwn$1(O, key = names[i++])) {
883
+ while (names.length > i) if (hasOwn$2(O, key = names[i++])) {
884
884
  ~indexOf$1(result, key) || push$1(result, key);
885
885
  }
886
886
  return result;
@@ -915,12 +915,12 @@ var objectGetOwnPropertySymbols = {};
915
915
  objectGetOwnPropertySymbols.f = Object.getOwnPropertySymbols;
916
916
 
917
917
  var getBuiltIn = getBuiltIn$3;
918
- var uncurryThis$1 = functionUncurryThis;
918
+ var uncurryThis$2 = functionUncurryThis;
919
919
  var getOwnPropertyNamesModule = objectGetOwnPropertyNames;
920
920
  var getOwnPropertySymbolsModule = objectGetOwnPropertySymbols;
921
921
  var anObject = anObject$2;
922
922
 
923
- var concat = uncurryThis$1([].concat);
923
+ var concat = uncurryThis$2([].concat);
924
924
 
925
925
  // all object keys, includes non-enumerable and symbols
926
926
  var ownKeys$1 = getBuiltIn('Reflect', 'ownKeys') || function ownKeys(it) {
@@ -929,25 +929,25 @@ var ownKeys$1 = getBuiltIn('Reflect', 'ownKeys') || function ownKeys(it) {
929
929
  return getOwnPropertySymbols ? concat(keys, getOwnPropertySymbols(it)) : keys;
930
930
  };
931
931
 
932
- var hasOwn = hasOwnProperty_1;
932
+ var hasOwn$1 = hasOwnProperty_1;
933
933
  var ownKeys = ownKeys$1;
934
934
  var getOwnPropertyDescriptorModule = objectGetOwnPropertyDescriptor;
935
935
  var definePropertyModule$1 = objectDefineProperty;
936
936
 
937
- var copyConstructorProperties$1 = function (target, source, exceptions) {
937
+ var copyConstructorProperties$2 = function (target, source, exceptions) {
938
938
  var keys = ownKeys(source);
939
939
  var defineProperty = definePropertyModule$1.f;
940
940
  var getOwnPropertyDescriptor = getOwnPropertyDescriptorModule.f;
941
941
  for (var i = 0; i < keys.length; i++) {
942
942
  var key = keys[i];
943
- if (!hasOwn(target, key) && !(exceptions && hasOwn(exceptions, key))) {
943
+ if (!hasOwn$1(target, key) && !(exceptions && hasOwn$1(exceptions, key))) {
944
944
  defineProperty(target, key, getOwnPropertyDescriptor(source, key));
945
945
  }
946
946
  }
947
947
  };
948
948
 
949
949
  var fails$2 = fails$a;
950
- var isCallable$1 = isCallable$b;
950
+ var isCallable$2 = isCallable$c;
951
951
 
952
952
  var replacement = /#|\.prototype\./;
953
953
 
@@ -955,7 +955,7 @@ var isForced$1 = function (feature, detection) {
955
955
  var value = data[normalize(feature)];
956
956
  return value == POLYFILL ? true
957
957
  : value == NATIVE ? false
958
- : isCallable$1(detection) ? fails$2(detection)
958
+ : isCallable$2(detection) ? fails$2(detection)
959
959
  : !!detection;
960
960
  };
961
961
 
@@ -969,12 +969,12 @@ var POLYFILL = isForced$1.POLYFILL = 'P';
969
969
 
970
970
  var isForced_1 = isForced$1;
971
971
 
972
- var global$1 = global$a;
972
+ var global$2 = global$b;
973
973
  var getOwnPropertyDescriptor = objectGetOwnPropertyDescriptor.f;
974
974
  var createNonEnumerableProperty = createNonEnumerableProperty$2;
975
975
  var defineBuiltIn = defineBuiltIn$1;
976
976
  var defineGlobalProperty = defineGlobalProperty$3;
977
- var copyConstructorProperties = copyConstructorProperties$1;
977
+ var copyConstructorProperties$1 = copyConstructorProperties$2;
978
978
  var isForced = isForced_1;
979
979
 
980
980
  /*
@@ -998,11 +998,11 @@ var _export = function (options, source) {
998
998
  var STATIC = options.stat;
999
999
  var FORCED, target, key, targetProperty, sourceProperty, descriptor;
1000
1000
  if (GLOBAL) {
1001
- target = global$1;
1001
+ target = global$2;
1002
1002
  } else if (STATIC) {
1003
- target = global$1[TARGET] || defineGlobalProperty(TARGET, {});
1003
+ target = global$2[TARGET] || defineGlobalProperty(TARGET, {});
1004
1004
  } else {
1005
- target = (global$1[TARGET] || {}).prototype;
1005
+ target = (global$2[TARGET] || {}).prototype;
1006
1006
  }
1007
1007
  if (target) for (key in source) {
1008
1008
  sourceProperty = source[key];
@@ -1014,7 +1014,7 @@ var _export = function (options, source) {
1014
1014
  // contained in target
1015
1015
  if (!FORCED && targetProperty !== undefined) {
1016
1016
  if (typeof sourceProperty == typeof targetProperty) continue;
1017
- copyConstructorProperties(sourceProperty, targetProperty);
1017
+ copyConstructorProperties$1(sourceProperty, targetProperty);
1018
1018
  }
1019
1019
  // add a flag to not completely full polyfills
1020
1020
  if (options.sham || (targetProperty && targetProperty.sham)) {
@@ -1024,14 +1024,6 @@ var _export = function (options, source) {
1024
1024
  }
1025
1025
  };
1026
1026
 
1027
- var tryToString = tryToString$2;
1028
-
1029
- var $TypeError = TypeError;
1030
-
1031
- var deletePropertyOrThrow$1 = function (O, P) {
1032
- if (!delete O[P]) throw $TypeError('Cannot delete property ' + tryToString(P) + ' of ' + tryToString(O));
1033
- };
1034
-
1035
1027
  var wellKnownSymbol$1 = wellKnownSymbol$3;
1036
1028
 
1037
1029
  var TO_STRING_TAG$1 = wellKnownSymbol$1('toStringTag');
@@ -1042,7 +1034,7 @@ test$1[TO_STRING_TAG$1] = 'z';
1042
1034
  var toStringTagSupport = String(test$1) === '[object z]';
1043
1035
 
1044
1036
  var TO_STRING_TAG_SUPPORT = toStringTagSupport;
1045
- var isCallable = isCallable$b;
1037
+ var isCallable$1 = isCallable$c;
1046
1038
  var classofRaw = classofRaw$2;
1047
1039
  var wellKnownSymbol = wellKnownSymbol$3;
1048
1040
 
@@ -1068,18 +1060,83 @@ var classof$1 = TO_STRING_TAG_SUPPORT ? classofRaw : function (it) {
1068
1060
  // builtinTag case
1069
1061
  : CORRECT_ARGUMENTS ? classofRaw(O)
1070
1062
  // ES3 arguments fallback
1071
- : (result = classofRaw(O)) == 'Object' && isCallable(O.callee) ? 'Arguments' : result;
1063
+ : (result = classofRaw(O)) == 'Object' && isCallable$1(O.callee) ? 'Arguments' : result;
1072
1064
  };
1073
1065
 
1074
1066
  var classof = classof$1;
1075
1067
 
1076
1068
  var $String = String;
1077
1069
 
1078
- var toString$1 = function (argument) {
1070
+ var toString$2 = function (argument) {
1079
1071
  if (classof(argument) === 'Symbol') throw TypeError('Cannot convert a Symbol value to a string');
1080
1072
  return $String(argument);
1081
1073
  };
1082
1074
 
1075
+ var $$2 = _export;
1076
+ var DESCRIPTORS = descriptors;
1077
+ var global$1 = global$b;
1078
+ var uncurryThis$1 = functionUncurryThis;
1079
+ var hasOwn = hasOwnProperty_1;
1080
+ var isCallable = isCallable$c;
1081
+ var isPrototypeOf = objectIsPrototypeOf;
1082
+ var toString$1 = toString$2;
1083
+ var defineProperty = objectDefineProperty.f;
1084
+ var copyConstructorProperties = copyConstructorProperties$2;
1085
+
1086
+ var NativeSymbol = global$1.Symbol;
1087
+ var SymbolPrototype = NativeSymbol && NativeSymbol.prototype;
1088
+
1089
+ if (DESCRIPTORS && isCallable(NativeSymbol) && (!('description' in SymbolPrototype) ||
1090
+ // Safari 12 bug
1091
+ NativeSymbol().description !== undefined
1092
+ )) {
1093
+ var EmptyStringDescriptionStore = {};
1094
+ // wrap Symbol constructor for correct work with undefined description
1095
+ var SymbolWrapper = function Symbol() {
1096
+ var description = arguments.length < 1 || arguments[0] === undefined ? undefined : toString$1(arguments[0]);
1097
+ var result = isPrototypeOf(SymbolPrototype, this)
1098
+ ? new NativeSymbol(description)
1099
+ // in Edge 13, String(Symbol(undefined)) === 'Symbol(undefined)'
1100
+ : description === undefined ? NativeSymbol() : NativeSymbol(description);
1101
+ if (description === '') EmptyStringDescriptionStore[result] = true;
1102
+ return result;
1103
+ };
1104
+
1105
+ copyConstructorProperties(SymbolWrapper, NativeSymbol);
1106
+ SymbolWrapper.prototype = SymbolPrototype;
1107
+ SymbolPrototype.constructor = SymbolWrapper;
1108
+
1109
+ var NATIVE_SYMBOL = String(NativeSymbol('test')) == 'Symbol(test)';
1110
+ var thisSymbolValue = uncurryThis$1(SymbolPrototype.valueOf);
1111
+ var symbolDescriptiveString = uncurryThis$1(SymbolPrototype.toString);
1112
+ var regexp = /^Symbol\((.*)\)[^)]+$/;
1113
+ var replace = uncurryThis$1(''.replace);
1114
+ var stringSlice = uncurryThis$1(''.slice);
1115
+
1116
+ defineProperty(SymbolPrototype, 'description', {
1117
+ configurable: true,
1118
+ get: function description() {
1119
+ var symbol = thisSymbolValue(this);
1120
+ if (hasOwn(EmptyStringDescriptionStore, symbol)) return '';
1121
+ var string = symbolDescriptiveString(symbol);
1122
+ var desc = NATIVE_SYMBOL ? stringSlice(string, 7, -1) : replace(string, regexp, '$1');
1123
+ return desc === '' ? undefined : desc;
1124
+ }
1125
+ });
1126
+
1127
+ $$2({ global: true, constructor: true, forced: true }, {
1128
+ Symbol: SymbolWrapper
1129
+ });
1130
+ }
1131
+
1132
+ var tryToString = tryToString$2;
1133
+
1134
+ var $TypeError = TypeError;
1135
+
1136
+ var deletePropertyOrThrow$1 = function (O, P) {
1137
+ if (!delete O[P]) throw $TypeError('Cannot delete property ' + tryToString(P) + ' of ' + tryToString(O));
1138
+ };
1139
+
1083
1140
  var toPropertyKey = toPropertyKey$3;
1084
1141
  var definePropertyModule = objectDefineProperty;
1085
1142
  var createPropertyDescriptor = createPropertyDescriptor$3;
@@ -1184,7 +1241,7 @@ var aCallable = aCallable$2;
1184
1241
  var toObject = toObject$2;
1185
1242
  var lengthOfArrayLike = lengthOfArrayLike$3;
1186
1243
  var deletePropertyOrThrow = deletePropertyOrThrow$1;
1187
- var toString = toString$1;
1244
+ var toString = toString$2;
1188
1245
  var fails = fails$a;
1189
1246
  var internalSort = arraySort;
1190
1247
  var arrayMethodIsStrict = arrayMethodIsStrict$1;
@@ -1505,12 +1562,12 @@ ColumnCollection.prototype.initialize = function () {
1505
1562
 
1506
1563
  /**
1507
1564
  * Get the column by this name
1508
- * @param {String} column column name
1565
+ * @param {string} column column name
1509
1566
  * @returns {Object} the column object
1510
1567
  */
1511
1568
  ColumnCollection.prototype.get = function (column) {
1512
1569
  for (let i = 0, len = this.length; i < len; i++) {
1513
- if (this[i].name == column) {
1570
+ if (this[i].name === column) {
1514
1571
  return this[i];
1515
1572
  }
1516
1573
  }
@@ -1519,12 +1576,12 @@ ColumnCollection.prototype.get = function (column) {
1519
1576
 
1520
1577
  /**
1521
1578
  * Get the index of the column by this name
1522
- * @param {String} column column name
1579
+ * @param {string} column column name
1523
1580
  * @returns {int} the index of this column
1524
1581
  */
1525
1582
  ColumnCollection.prototype.indexOf = function (column) {
1526
1583
  for (let i = 0, len = this.length; i < len; i++) {
1527
- if (this[i].name == column) {
1584
+ if (this[i].name === column) {
1528
1585
  return i;
1529
1586
  }
1530
1587
  }
@@ -1533,12 +1590,12 @@ ColumnCollection.prototype.indexOf = function (column) {
1533
1590
 
1534
1591
  /**
1535
1592
  * Get the column by the specified order
1536
- * @param {Number} order the column's order
1593
+ * @param {number} order the column's order
1537
1594
  * @returns {Object} the column object
1538
1595
  */
1539
1596
  ColumnCollection.prototype.getByOrder = function (order) {
1540
1597
  for (let i = 0, len = this.length; i < len; i++) {
1541
- if (this[i].order == order) {
1598
+ if (this[i].order === order) {
1542
1599
  return this[i];
1543
1600
  }
1544
1601
  }
@@ -1632,27 +1689,6 @@ ColumnCollection.prototype.moveColumn = function (src, dest) {
1632
1689
 
1633
1690
  /* eslint-env browser */
1634
1691
 
1635
- const CssUtil = {};
1636
-
1637
- let _isTransformSupported = null;
1638
-
1639
- CssUtil.getSupportedTransform = () => {
1640
- if (_isTransformSupported === null) {
1641
- let prefixes = ['transform', 'WebkitTransform', 'MozTransform', 'OTransform', 'msTransform'];
1642
- let div = document.createElement('div');
1643
- _isTransformSupported = false;
1644
- for (let item of prefixes) {
1645
- if (div && div.style[item] !== undefined) {
1646
- _isTransformSupported = item;
1647
- break;
1648
- }
1649
- }
1650
- }
1651
- return _isTransformSupported;
1652
- };
1653
-
1654
- /* eslint-env browser */
1655
-
1656
1692
  // saveSelection/restoreSelection courtesy of Tim Down, with my improvements
1657
1693
  // https://stackoverflow.com/questions/13949059/persisting-the-changes-of-range-objects-after-selection-in-html/13950376#13950376
1658
1694
 
@@ -1706,12 +1742,1332 @@ class SelectionHelper {
1706
1742
  }
1707
1743
  }
1708
1744
  }
1709
-
1710
- let sel = window.getSelection();
1711
- sel.removeAllRanges();
1712
- sel.addRange(range);
1745
+
1746
+ let sel = window.getSelection();
1747
+ sel.removeAllRanges();
1748
+ sel.addRange(range);
1749
+ }
1750
+ }
1751
+
1752
+ /**
1753
+ * @typedef {function(index: number):(number|undefined)} VirtualListHelper~ItemHeightEstimatorFunction
1754
+ */
1755
+
1756
+ /**
1757
+ * @typedef {function():Element} VirtualListHelper~ItemElementCreatorFunction
1758
+ */
1759
+
1760
+ /**
1761
+ * @typedef {function(itemEl: Element, index: number)} VirtualListHelper~ItemRenderFunction
1762
+ */
1763
+
1764
+ /**
1765
+ * @typedef {function(itemEl: Element)} VirtualListHelper~ItemUnrenderFunction
1766
+ */
1767
+
1768
+ /**
1769
+ * @typedef {Object} VirtualListHelper~Options
1770
+ * @property {Element} list - the main element to operate inside of
1771
+ * @property {Element?} [itemsParent] - the element to use as parent for the items (automatically created in virtual mode, uses parent by default in non-virtual mode)
1772
+ * @property {boolean} [autoVirtualWrapperWidth=true] automatically set the width of the virtual wrapper
1773
+ * @property {boolean} [hookScrollEvent=true] automatically hook scroll event as needed
1774
+ * @property {number} [count=0] the item count
1775
+ * @property {boolean} [virtual=true] is virtual mode on?
1776
+ * @property {number} [estimatedItemHeight=20] estimated item height
1777
+ * @property {number} [buffer=5] the amount of buffer items to keep on each end of the list
1778
+ * @property {VirtualListHelper~ItemHeightEstimatorFunction} [itemHeightEstimatorFn] an optional function for providing item height estimations
1779
+ * @property {VirtualListHelper~ItemElementCreatorFunction} [itemElementCreatorFn] an optional function for providing fresh item elements (default creates `<li />`s)
1780
+ * @property {VirtualListHelper~ItemRenderFunction} [onItemRender] a function for rendering element content based on item index
1781
+ * @property {VirtualListHelper~ItemUnrenderFunction} [onItemUnrender] a function for freeing resources in an item element
1782
+ *
1783
+ */
1784
+
1785
+ /** */
1786
+
1787
+ const hasOwnProperty$1 = Object.prototype.hasOwnProperty;
1788
+
1789
+ class VirtualListHelper {
1790
+ /**
1791
+ * @param {VirtualListHelper~Options} opts
1792
+ */
1793
+ constructor(opts) {var _opts$autoVirtualWrap;
1794
+ /** @private */
1795
+ const p = this._p = {
1796
+ // these come from options:
1797
+
1798
+ list: opts.list || null,
1799
+ hookScrollEvent: opts.hookScrollEvent === undefined ? true : !!opts.hookScrollEvent,
1800
+ count: opts.count || 0,
1801
+ virtual: opts.virtual === undefined ? true : !!opts.virtual,
1802
+ userItemsParent: opts.itemsParent || null,
1803
+ setVirtualWrapperWidth: (_opts$autoVirtualWrap = opts.autoVirtualWrapperWidth) !== null && _opts$autoVirtualWrap !== void 0 ? _opts$autoVirtualWrap : true,
1804
+ estimatedItemHeight: 20,
1805
+ buffer: 5,
1806
+
1807
+ /** @type VirtualListHelper~ItemHeightEstimatorFunction|null */
1808
+ itemHeightEstimatorFn: null,
1809
+
1810
+ /** @type VirtualListHelper~ItemElementCreatorFunction|null */
1811
+ itemElementCreatorFn: defaultElementCreator,
1812
+
1813
+ /** @type VirtualListHelper~ItemRenderFunction|null */
1814
+ onItemRender: null,
1815
+
1816
+ /** @type VirtualListHelper~ItemUnrenderFunction|null */
1817
+ onItemUnrender: null,
1818
+
1819
+ // internal:
1820
+
1821
+ /** @type Element|null */
1822
+ virtualWrapper: null,
1823
+
1824
+ /** @type Element|null */
1825
+ currentItemsParent: null,
1826
+
1827
+ /** @type (number|undefined)[] */
1828
+ cachedItemHeights: [],
1829
+
1830
+ /** @type (number|undefined)[] */
1831
+ cachedItemEstimatedHeights: [],
1832
+
1833
+ /** @type (number|undefined)[] */
1834
+ cachedItemPositions: [],
1835
+
1836
+ /** @type number */
1837
+ itemPositionsNeedsUpdate: 0,
1838
+
1839
+ /** @type function */
1840
+ boundRender: this.render.bind(this),
1841
+
1842
+ /** @type Element[] */
1843
+ existingEls: []
1844
+ };
1845
+
1846
+ p.currentItemsParent = p.userItemsParent || p.list;
1847
+
1848
+ if (typeof opts.hookScrollEvent === 'boolean')
1849
+ this.setHookScrollEvent(opts.hookScrollEvent);else
1850
+ this._hookEvents();
1851
+
1852
+ if (typeof opts.count === 'number')
1853
+ this.setCount(opts.count);
1854
+
1855
+ if (typeof opts.virtual === 'boolean')
1856
+ this.setVirtual(opts.virtual);
1857
+
1858
+ if (typeof opts.estimatedItemHeight === 'number')
1859
+ this.setEstimatedItemHeight(opts.estimatedItemHeight);
1860
+
1861
+ if (typeof opts.buffer === 'number')
1862
+ this.setBuffer(opts.buffer);
1863
+
1864
+ if (typeof opts.itemHeightEstimatorFn === 'function')
1865
+ this.setItemHeightEstimatorFn(opts.itemHeightEstimatorFn);
1866
+
1867
+ if (typeof opts.itemElementCreatorFn === 'function')
1868
+ this.setItemElementCreatorFn(opts.itemElementCreatorFn);
1869
+
1870
+ if (typeof opts.onItemRender === 'function')
1871
+ this.setOnItemRender(opts.onItemRender);
1872
+
1873
+ if (typeof opts.onItemUnrender === 'function')
1874
+ this.setOnItemUnrender(opts.onItemUnrender);
1875
+ }
1876
+
1877
+ /**
1878
+ * Clean up and free up all resources.
1879
+ */
1880
+ destroy() {
1881
+ this._unhookEvents().invalidate()._destroyElements();
1882
+ }
1883
+
1884
+ /**
1885
+ * Sets whether 'scroll' event on the list should be hooked automatically.
1886
+ * @param {boolean} enabled
1887
+ * @returns {VirtualListHelper}
1888
+ */
1889
+ setHookScrollEvent(enabled) {
1890
+ const p = this._p;
1891
+ enabled = enabled === undefined ? true : !!enabled;
1892
+
1893
+ if (p.hookScrollEvent === enabled)
1894
+ return this;
1895
+
1896
+ p.hookScrollEvent = enabled;
1897
+
1898
+ this._unhookEvents()._hookEvents();
1899
+
1900
+ return this;
1901
+ }
1902
+
1903
+ /**
1904
+ * @returns {boolean} whether 'scroll' event on the list should be hooked automatically
1905
+ */
1906
+ isHookScrollEventEnabled() {
1907
+ const p = this._p;
1908
+ return p.hookScrollEvent;
1909
+ }
1910
+
1911
+ /**
1912
+ * Sets the list item count. <br />
1913
+ * You should probably call `render()` after this.
1914
+ * @param {number} count
1915
+ * @returns {VirtualListHelper}
1916
+ */
1917
+ setCount(count) {
1918
+ const p = this._p;
1919
+ p.count = count;
1920
+
1921
+ return this.invalidatePositions();
1922
+ }
1923
+
1924
+ /**
1925
+ * @returns {number} current item count
1926
+ */
1927
+ getCount() {
1928
+ const p = this._p;
1929
+ return p.count;
1930
+ }
1931
+
1932
+ /**
1933
+ * Switches between virtual and non-virtual mode. <br />
1934
+ * The list is invalidated automatically. <br />
1935
+ * You should call `render()` to update the view.
1936
+ * @param {boolean} enabled
1937
+ * @returns {VirtualListHelper}
1938
+ */
1939
+ setVirtual(enabled) {
1940
+ const p = this._p;
1941
+ enabled = enabled === undefined ? true : !!enabled;
1942
+
1943
+ if (p.virtual === enabled)
1944
+ return this;
1945
+
1946
+ p.virtual = enabled;
1947
+
1948
+ this._hookEvents().invalidate()._destroyElements();
1949
+
1950
+ return this;
1951
+ }
1952
+
1953
+ /**
1954
+ * @returns {boolean} virtual mode
1955
+ */
1956
+ isVirtual() {
1957
+ const p = this._p;
1958
+ return p.virtual;
1959
+ }
1960
+
1961
+ /**
1962
+ * Sets estimated item height. <br />
1963
+ * No need to be accurate. <br />
1964
+ * The better the estimation - the better the scrollbar behavior will be. <br />
1965
+ * Applicable for virtual-mode only. <br />
1966
+ * You should `invalidate` if you want this to take effect on the existing rendering.
1967
+ * @param {number} height - a positive number representing estimated item height.
1968
+ * @returns {VirtualListHelper}
1969
+ */
1970
+ setEstimatedItemHeight(height) {
1971
+ const p = this._p;
1972
+ p.estimatedItemHeight = Math.abs((typeof height === 'number' ? height : Number(height)) || 20);
1973
+ return this;
1974
+ }
1975
+
1976
+ /**
1977
+ * @returns {number} current item height estimation
1978
+ */
1979
+ getEstimatedItemHeight() {
1980
+ const p = this._p;
1981
+ return p.estimatedItemHeight;
1982
+ }
1983
+
1984
+ /**
1985
+ * Sets whether the virtual wrapper width should be set automatically. <br />
1986
+ * @param {boolean} enabled
1987
+ * @returns {VirtualListHelper}
1988
+ */
1989
+ setAutoVirtualWrapperWidth(enabled) {
1990
+ const p = this._p;
1991
+ p.autoVirtualWrapperWidth = enabled === undefined ? true : !!enabled;
1992
+
1993
+ if (p.virtualWrapper) {
1994
+ if (p.autoVirtualWrapperWidth !== p.virtualWrapperWidthWasSet) {
1995
+ p.virtualWrapper.style.width = p.autoVirtualWrapperWidth ? '100%' : '';
1996
+ p.virtualWrapperWidthWasSet = p.autoVirtualWrapperWidth;
1997
+ }
1998
+ }
1999
+
2000
+ return this;
2001
+ }
2002
+
2003
+ /**
2004
+ * @returns {boolean} whether the virtual wrapper width should be set automatically
2005
+ */
2006
+ isAutoVirtualWrapperWidth() {
2007
+ const p = this._p;
2008
+ return p.autoVirtualWrapperWidth;
2009
+ }
2010
+
2011
+ /**
2012
+ * Sets the amount of buffer items to keep on each end of the list. <br />
2013
+ * Applicable for virtual-mode only.
2014
+ * @param {number} buffer - a positive value representing the count of buffer items for each end.
2015
+ * @returns {VirtualListHelper}
2016
+ */
2017
+ setBuffer(buffer) {
2018
+ const p = this._p;
2019
+ p.buffer = Math.abs(typeof buffer === 'number' ? buffer : Number(buffer) || 5);
2020
+ return this;
2021
+ }
2022
+
2023
+ /**
2024
+ * @returns {number} current buffer value
2025
+ */
2026
+ getBuffer() {
2027
+ const p = this._p;
2028
+ return p.buffer;
2029
+ }
2030
+
2031
+ /**
2032
+ * The `itemHeightEstimatorFn` is an alternative to `estimatedItemHeight` to give better estimations for specific item. <br/>
2033
+ * It's optional, and if it's present - it should return either a numeric height estimation,
2034
+ * or `undefined` to fall back to the default estimation. <br />
2035
+ * You should `invalidate` if you want this to take effect on the existing rendering.
2036
+ * @param {VirtualListHelper~ItemHeightEstimatorFunction} fn
2037
+ * @returns {VirtualListHelper}
2038
+ */
2039
+ setItemHeightEstimatorFn(fn) {
2040
+ const p = this._p;
2041
+ p.itemHeightEstimatorFn = fn;
2042
+ return this;
2043
+ }
2044
+
2045
+ /**
2046
+ * The `itemElementCreatorFn` is a function creating a basic item element, that will be possibly reused later. <br />
2047
+ * It has no association with a specific item index. <br />
2048
+ * You should `invalidate` if you want this to take effect on the existing rendering.
2049
+ * @param {VirtualListHelper~ItemElementCreatorFunction} fn
2050
+ * @returns {VirtualListHelper}
2051
+ */
2052
+ setItemElementCreatorFn(fn) {
2053
+ const p = this._p;
2054
+ p.itemElementCreatorFn = fn || defaultElementCreator;
2055
+ return this;
2056
+ }
2057
+
2058
+ /**
2059
+ * The `onItemRender` is a function called for rendering the contents of an item. <br />
2060
+ * It's passed an `Element` and an item index. <br />
2061
+ * You should `invalidate` if you want this to take effect on the existing rendering.
2062
+ * @param {VirtualListHelper~ItemRenderFunction} fn
2063
+ * @returns {VirtualListHelper}
2064
+ */
2065
+ setOnItemRender(fn) {
2066
+ const p = this._p;
2067
+ p.onItemRender = fn;
2068
+ return this;
2069
+ }
2070
+
2071
+ /**
2072
+ * The `onItemUnrender` is a function called for freeing resources in an item element,
2073
+ * if you've attached something that needs to be explicitly freed. <br />
2074
+ * It's passed an `Element` only, and has no association with a specific index,
2075
+ * as by the time it's called - the indexes are probably not valid anymore.
2076
+ * @param {VirtualListHelper~ItemUnrenderFunction} fn
2077
+ * @returns {VirtualListHelper}
2078
+ */
2079
+ setOnItemUnrender(fn) {
2080
+ const p = this._p;
2081
+ p.onItemUnrender = fn;
2082
+ return this;
2083
+ }
2084
+
2085
+ /**
2086
+ * Estimates the full scroll height. This gets better as more renderings occur.
2087
+ * @returns {number}
2088
+ */
2089
+ estimateFullHeight() {
2090
+ const p = this._p;
2091
+
2092
+ if (p.count === 0)
2093
+ return 0;
2094
+
2095
+ if (p.virtual) {
2096
+ return this._calculateItemPosition(p.count) || 0;
2097
+ } else {
2098
+ const existingEls = p.existingEls;
2099
+ if (p.count === existingEls.length) {
2100
+ let rect1 = existingEls[0].getBoundingClientRect();
2101
+ let rect2 = existingEls[existingEls.length - 1].getBoundingClientRect();
2102
+ return rect2.top - rect1.top + rect2.height;
2103
+ }
2104
+
2105
+ return this._calculateItemPosition(p.count) || 0;
2106
+ }
2107
+ }
2108
+
2109
+ /**
2110
+ * States that the cached positions/heights are invalid,
2111
+ * and needs to be completely re-calculated.<br />
2112
+ * You should probably call `render()` after this.
2113
+ * @returns {VirtualListHelper}
2114
+ */
2115
+ invalidatePositions() {
2116
+ const p = this._p;
2117
+
2118
+ p.itemPositionsNeedsUpdate = 0;
2119
+ p.cachedItemHeights = [];
2120
+ p.cachedItemEstimatedHeights = [];
2121
+ p.cachedItemPositions = [];
2122
+ p.cachedItemHeights.length = p.count;
2123
+ p.cachedItemEstimatedHeights.length = p.count;
2124
+ p.cachedItemPositions.length = p.count;
2125
+
2126
+ return this;
2127
+ }
2128
+
2129
+ /**
2130
+ * States that the indexes/item count/rendered content are invalid,
2131
+ * and needs to be completely re-calculated and re-rendered. <br />
2132
+ * You should probably call `render()` after this.
2133
+ * @returns {VirtualListHelper}
2134
+ */
2135
+ invalidate() {
2136
+ const p = this._p;
2137
+
2138
+ this.invalidatePositions();
2139
+
2140
+ const onItemUnrender = p.onItemUnrender;
2141
+ const existingEls = p.existingEls;
2142
+
2143
+ for (let i = 0; i < existingEls.length; i++) {
2144
+ const el = existingEls[i];
2145
+ const itemIndex = el[ItemIndexSymbol];
2146
+ if (itemIndex === undefined) continue;
2147
+
2148
+ if (onItemUnrender)
2149
+ onItemUnrender(el);
2150
+
2151
+ delete el[ItemIndexSymbol];
2152
+ }
2153
+
2154
+ return this;
2155
+ }
2156
+
2157
+ /**
2158
+ * Renders the current viewport. <br />
2159
+ * Call this after making changes to the list. <br />
2160
+ * In virtual mode, this is called automatically for every scroll event.
2161
+ */
2162
+ render() {
2163
+ const p = this._p;
2164
+ const list = p.list;
2165
+ const virtual = p.virtual;
2166
+ let virtualWrapper = p.virtualWrapper;
2167
+ let scrollTop = list.scrollTop;
2168
+ let visibleHeight = list.clientHeight;
2169
+ let visibleBottom = scrollTop + visibleHeight;
2170
+ let count = p.count;
2171
+ let buffer = p.buffer;
2172
+ let onItemUnrender = p.onItemUnrender;
2173
+ let existingEls = p.existingEls;
2174
+ let existingCount = existingEls.length;
2175
+
2176
+ if (virtual) {
2177
+ const originalWidth = list.clientWidth;
2178
+
2179
+ if (!virtualWrapper) {
2180
+ virtualWrapper = p.virtualWrapper = p.userItemsParent;
2181
+ if (!virtualWrapper) {
2182
+ virtualWrapper = p.virtualWrapper = document.createElement('div');
2183
+ list.appendChild(virtualWrapper);
2184
+ }
2185
+
2186
+ this._resetCurrentItemsParent();
2187
+
2188
+ if (p.autoVirtualWrapperWidth) {
2189
+ virtualWrapper.style.width = '100%';
2190
+ p.virtualWrapperWidthWasSet = true;
2191
+ } else {
2192
+ p.virtualWrapperWidthWasSet = false;
2193
+ }
2194
+ }
2195
+
2196
+ // Mark all of them for potential reuse
2197
+ for (let i = 0; i < existingCount; i++) {
2198
+ existingEls[i][ReuseElSymbol] = true;
2199
+ }
2200
+
2201
+ // Make sure we have at least estimated positions for all items so we can translate scroll position
2202
+ this._calculateItemPosition(p.count - 1);
2203
+
2204
+ // Find existing elements index range
2205
+ let existingRange = this._getExistingElsRange();
2206
+
2207
+ // Find first visible element
2208
+ let firstVisibleIndex = binarySearchPosition(p.cachedItemPositions, scrollTop);
2209
+ let firstRenderIndex = Math.max(0, firstVisibleIndex - buffer);
2210
+
2211
+ // Iterate over viewport
2212
+ let index = firstRenderIndex;
2213
+ let renderPos = this._calculateItemPosition(index);
2214
+ let bufferEnd = buffer;
2215
+
2216
+ /** @type Node|undefined */
2217
+ let lastEl = undefined;
2218
+
2219
+ // If rendering position has not reached the viewport bottom
2220
+ // AND we have not rendered all the buffer items yet
2221
+ while ((renderPos < visibleBottom || bufferEnd-- > 0) && index < count) {
2222
+ // Find existing element to reuse
2223
+ /** @type Element|undefined */
2224
+ let existingEl = undefined;
2225
+
2226
+ if (existingRange.firstIndex !== -1 && index >= existingRange.firstIndex && index <= existingRange.lastIndex) {
2227
+ existingEl = existingEls.find((x) => x[ItemIndexSymbol] === index && x[ReuseElSymbol] === true);
2228
+ }
2229
+
2230
+ if (existingEl === undefined) {
2231
+ existingEl = (existingRange.firstIndex < firstRenderIndex || existingRange.firstValidArrayIndex > 0 ?
2232
+ existingEls.find((x) =>
2233
+ (x[ItemIndexSymbol] < firstRenderIndex || false === hasOwnProperty$1.call(x, ItemIndexSymbol)) &&
2234
+ x[ReuseElSymbol] === true) :
2235
+ undefined) ||
2236
+ findLast(existingEls, (x) => x[ReuseElSymbol] === true);
2237
+ }
2238
+
2239
+ if (existingEl !== undefined) {
2240
+ delete existingEl[ReuseElSymbol];
2241
+ }
2242
+
2243
+ // Find the element to insert before
2244
+ let insertBefore = lastEl ? lastEl.nextSibling : virtualWrapper.childNodes[0];
2245
+ if (insertBefore && insertBefore === existingEl)
2246
+ insertBefore = insertBefore.nextSibling;
2247
+
2248
+ // Dequeue the element by reusing or creating a new one
2249
+ lastEl = this._dequeueElementForIndex(existingEl, index, insertBefore);
2250
+
2251
+ // Increment pointers
2252
+ renderPos = p.cachedItemPositions[index] + p.cachedItemHeights[index];
2253
+ index++;
2254
+ }
2255
+
2256
+ // Calculate up to date scroll height
2257
+ let scrollHeight = this.estimateFullHeight();
2258
+ p.virtualWrapper.style.height = scrollHeight + 'px';
2259
+
2260
+ if (originalWidth !== list.clientWidth)
2261
+ this.render();
2262
+ } else {// non-virtual
2263
+ if (count !== existingEls.length) {
2264
+ for (let i = 0; i < existingCount; i++) {
2265
+ existingEls[i][ReuseElSymbol] = true;
2266
+ }
2267
+
2268
+ /** @type Node|undefined */
2269
+ let lastEl = undefined;
2270
+ for (let index = 0; index < count; index++) {
2271
+ // Find existing element to reuse
2272
+ let existingEl = existingEls.find((x) => x[ItemIndexSymbol] === index && x[ReuseElSymbol] === true);
2273
+
2274
+ if (existingEl !== undefined) {
2275
+ delete existingEl[ReuseElSymbol];
2276
+ }
2277
+
2278
+ // Find the element to insert before
2279
+ let insertBefore = lastEl ? lastEl.nextSibling : list.childNodes[0];
2280
+ if (insertBefore && insertBefore === existingEl)
2281
+ insertBefore = insertBefore.nextSibling;
2282
+
2283
+ // Dequeue the element by reusing or creating a new one
2284
+ lastEl = this._dequeueElementForIndex(existingEl, index, insertBefore);
2285
+ }
2286
+ }
2287
+ }
2288
+
2289
+ // Cleanup extra unused elements
2290
+ existingCount = existingEls.length; // May have changed
2291
+ for (let i = 0; i < existingCount; i++) {
2292
+ const el = existingEls[i];
2293
+ if (el[ReuseElSymbol] !== true) continue;
2294
+
2295
+ let parent = el.parentNode;
2296
+ if (parent)
2297
+ parent.removeChild(el);
2298
+ if (onItemUnrender && el[ItemIndexSymbol] !== undefined)
2299
+ onItemUnrender(el);
2300
+ existingEls.splice(i, 1);
2301
+
2302
+ i--;
2303
+ existingCount--;
2304
+ }
2305
+ }
2306
+
2307
+ /**
2308
+ * States that items were added at a certain position in the list. <br />
2309
+ * Virtual mode: Call `render()` to update the view after making changes.
2310
+ * @param {number} count
2311
+ * @param {number} [atIndex=-1]
2312
+ * @returns {VirtualListHelper}
2313
+ */
2314
+ addItemsAt(count, atIndex = -1) {
2315
+ if (typeof count !== 'number' || count <= 0)
2316
+ return this;
2317
+
2318
+ const p = this._p;
2319
+
2320
+ if (atIndex < -1 || atIndex >= p.count)
2321
+ atIndex = p.count;
2322
+
2323
+ p.count += count;
2324
+
2325
+ if (p.virtual) {
2326
+ if (atIndex >= 0 && atIndex < p.count) {
2327
+ this._invalidateItemIndexesAt(atIndex, -1);
2328
+ }
2329
+ } else
2330
+ {// non-virtual
2331
+ let existingEls = p.existingEls;
2332
+ let existingCount = existingEls.length;
2333
+ if (existingCount !== p.count - count)
2334
+ return this;
2335
+
2336
+ let existingRange = this._getExistingElsRange();
2337
+ if (existingRange.firstValidArrayIndex === -1)
2338
+ return this;
2339
+
2340
+ let startIndex = existingRange.firstValidArrayIndex + atIndex - existingRange.firstIndex;
2341
+
2342
+ this._pushItemIndexesAt(atIndex, count);
2343
+
2344
+ /** @type Node|undefined */
2345
+ let lastEl = existingEls[startIndex - 1];
2346
+
2347
+ for (let index = atIndex, end = atIndex + count; index < end; index++) {
2348
+ let insertBefore = lastEl ? lastEl.nextSibling : existingEls[0];
2349
+ lastEl = this._dequeueElementForIndex(undefined, index, insertBefore);
2350
+ }
2351
+ }
2352
+
2353
+ return this;
2354
+ }
2355
+
2356
+ /**
2357
+ * States that items were removed at a certain position in the list. <br />
2358
+ * Virtual mode: Call `render()` to update the view after making changes.
2359
+ * @param {number} count
2360
+ * @param {number} atIndex
2361
+ * @returns {VirtualListHelper}
2362
+ */
2363
+ removeItemsAt(count, atIndex) {
2364
+ const p = this._p;
2365
+
2366
+ if (typeof count !== 'number' || typeof atIndex !== 'number' || count <= 0 || atIndex < 0 || atIndex >= p.count)
2367
+ return this;
2368
+
2369
+ p.count -= Math.min(count, p.count - atIndex);
2370
+
2371
+ if (p.virtual) {
2372
+ this._invalidateItemIndexesAt(atIndex, -1);
2373
+ } else
2374
+ {// non-virtual
2375
+ let existingEls = p.existingEls;
2376
+ let existingCount = existingEls.length;
2377
+ if (existingCount !== p.count + count)
2378
+ return this;
2379
+
2380
+ let existingRange = this._getExistingElsRange();
2381
+ if (existingRange.firstValidArrayIndex === -1)
2382
+ return this;
2383
+
2384
+ this._pushItemIndexesAt(atIndex + count, -count);
2385
+
2386
+ const onItemUnrender = p.onItemUnrender;
2387
+ let index = existingRange.firstValidArrayIndex + atIndex - existingRange.firstIndex;
2388
+ if (index < existingEls.length) {
2389
+ for (let i = 0; i < count; i++) {
2390
+ let itemEl = existingEls[index + i];
2391
+
2392
+ let parent = itemEl.parentNode;
2393
+ if (parent)
2394
+ parent.removeChild(itemEl);
2395
+ if (onItemUnrender && itemEl[ItemIndexSymbol] !== undefined)
2396
+ onItemUnrender(itemEl);
2397
+ }
2398
+ existingEls.splice(index, count);
2399
+ }
2400
+ }
2401
+
2402
+ return this;
2403
+ }
2404
+
2405
+ /**
2406
+ * Mark an element for a re-render. <br />
2407
+ * Virtual mode: Call `render()` to update the view after making changes. <br />
2408
+ * Non-virtual mode - the element is re-rendered immediately.
2409
+ * @param {number} index - the index of the element to re-render
2410
+ * @returns {VirtualListHelper}
2411
+ */
2412
+ refreshItemAt(index) {
2413
+ const p = this._p;
2414
+
2415
+ if (typeof index !== 'number' || index < 0 || index >= p.count)
2416
+ return this;
2417
+
2418
+ if (p.virtual) {
2419
+ this._invalidateItemIndexesAt(index, 1);
2420
+ } else
2421
+ {// non-virtual
2422
+ let existingEls = p.existingEls;
2423
+ let existingCount = existingEls.length;
2424
+ if (existingCount !== p.count)
2425
+ return this;
2426
+
2427
+ let existingRange = this._getExistingElsRange();
2428
+
2429
+ if (index >= existingRange.firstIndex && index <= existingRange.lastIndex) {
2430
+ let itemEl = existingEls[existingRange.firstValidArrayIndex + index - existingRange.firstIndex];
2431
+ delete itemEl[ItemIndexSymbol];
2432
+ this._dequeueElementForIndex(itemEl, index, itemEl.nextSibling);
2433
+ }
2434
+ }
2435
+
2436
+ return this;
2437
+ }
2438
+
2439
+ /**
2440
+ * Tests whether an item at the specified index is rendered.
2441
+ * @param {number} index - the index to test
2442
+ * @returns {boolean}
2443
+ */
2444
+ isItemRendered(index) {
2445
+ const p = this._p;
2446
+
2447
+ if (typeof index !== 'number' || index < 0 || index >= p.count)
2448
+ return false;
2449
+
2450
+ let existingRange = this._getExistingElsRange();
2451
+
2452
+ return index >= existingRange.firstIndex && index <= existingRange.lastIndex;
2453
+ }
2454
+
2455
+ /**
2456
+ * Retrieves DOM element for the item at the specified index - if it's currently rendered.
2457
+ * @param {number} index - the index to retrieve
2458
+ * @returns {Element|undefined}
2459
+ */
2460
+ getItemElementAt(index) {
2461
+ const p = this._p;
2462
+
2463
+ if (typeof index !== 'number' || index < 0 || index >= p.count)
2464
+ return undefined;
2465
+
2466
+ let existingEls = p.existingEls;
2467
+ let existingRange = this._getExistingElsRange();
2468
+
2469
+ if (index >= existingRange.firstIndex && index <= existingRange.lastIndex) {
2470
+ return existingEls[existingRange.firstValidArrayIndex + index - existingRange.firstIndex];
2471
+ }
2472
+
2473
+ return undefined;
2474
+ }
2475
+
2476
+ /**
2477
+ * Retrieves the position for the specified index. <br />
2478
+ * Can be used to scroll to a specific item.
2479
+ * @param {number} index
2480
+ * @returns {number|undefined}
2481
+ */
2482
+ getItemPosition(index) {
2483
+ const p = this._p;
2484
+
2485
+ if (typeof index !== 'number' || index < 0 || index >= p.count)
2486
+ return undefined;
2487
+
2488
+ if (p.virtual) {
2489
+ return this._calculateItemPosition(index);
2490
+ } else {
2491
+ let itemEl = this.getItemElementAt(index);
2492
+ if (itemEl === undefined)
2493
+ return undefined;
2494
+
2495
+ const list = p.list;
2496
+ return Css.getElementOffset(itemEl).top - Css.getElementOffset(list).top + list.scrollTop;
2497
+ }
2498
+ }
2499
+
2500
+ /**
2501
+ * Retrieves the item index for the specified element
2502
+ * @param {Element} el
2503
+ * @returns {number|undefined}
2504
+ */
2505
+ getItemIndexFromElement(el) {
2506
+ return el ? el[ItemIndexSymbol] : undefined;
2507
+ }
2508
+
2509
+ /**
2510
+ * Retrieves the size (or estimated size, if unknown) for the specified index. <br />
2511
+ * @param {number} index
2512
+ * @returns {number|undefined}
2513
+ */
2514
+ getItemSize(index) {
2515
+ const p = this._p;
2516
+
2517
+ if (typeof index !== 'number' || index < 0 || index >= p.count)
2518
+ return undefined;
2519
+
2520
+ let height = p.cachedItemHeights[index - 1]; // already calculated
2521
+
2522
+ if (height === undefined) {
2523
+ height = p.itemHeightEstimatorFn ? p.itemHeightEstimatorFn(index - 1) : null; // estimated per item
2524
+
2525
+ if (typeof height !== 'number')
2526
+ height = p.estimatedItemHeight; // estimated
2527
+
2528
+ p.cachedItemEstimatedHeights[index - 1] = height;
2529
+ }
2530
+
2531
+ return height;
2532
+ }
2533
+
2534
+ /**
2535
+ * Retrieves the number of items that fit into the current viewport.
2536
+ * @returns {number}
2537
+ */
2538
+ getVisibleItemCount() {
2539
+ const p = this._p,list = p.list;
2540
+
2541
+ let scrollTop = list.scrollTop;
2542
+ let visibleHeight = list.clientHeight;
2543
+ let firstVisibleIndex, lastVisibleIndex;
2544
+
2545
+ if (p.virtual) {
2546
+ firstVisibleIndex = binarySearchPosition(p.cachedItemPositions, scrollTop);
2547
+ lastVisibleIndex = binarySearchPosition(p.cachedItemPositions, scrollTop + visibleHeight, firstVisibleIndex);
2548
+ } else
2549
+ {
2550
+ const retriever = (i) => {
2551
+ let pos = this.getItemPosition(i);
2552
+ if (pos === undefined)
2553
+ pos = Infinity;
2554
+ return pos;
2555
+ };
2556
+
2557
+ firstVisibleIndex = binarySearchPositionByFn(p.count, retriever, scrollTop);
2558
+ lastVisibleIndex = binarySearchPositionByFn(p.count, retriever, scrollTop + visibleHeight, firstVisibleIndex);
2559
+ }
2560
+
2561
+ if (this.getItemPosition(lastVisibleIndex) === scrollTop + visibleHeight)
2562
+ lastVisibleIndex--;
2563
+ return lastVisibleIndex - firstVisibleIndex + 1;
2564
+ }
2565
+
2566
+ /**
2567
+ * Renders a temporary ghost item. Can be used for testings several aspects of a proposed element, i.e measurements.
2568
+ * @param {*} ghostIndex - the value to pass as the index for the renderer function
2569
+ * @param {boolean} append - whether to append the item element to the DOM
2570
+ * @param {function(itemEl: Element)} ghostTester - the function that will receive the element, called synchronously.
2571
+ */
2572
+ createGhostItemElement(ghostIndex, append, ghostTester) {
2573
+ const p = this._p;
2574
+
2575
+ let itemEl = this._dequeueElementForIndex(null, ghostIndex, false);
2576
+ try {
2577
+ if (append) {
2578
+ p.currentItemsParent.appendChild(itemEl);
2579
+ }
2580
+ ghostTester(itemEl);
2581
+ } finally {
2582
+ if (append) {
2583
+ let parent = itemEl.parentNode;
2584
+ if (parent)
2585
+ parent.removeChild(itemEl);
2586
+ }
2587
+ if (p.onItemUnrender)
2588
+ p.onItemUnrender(itemEl);
2589
+ }
2590
+ }
2591
+
2592
+ /**
2593
+ * Reset the pointer to the current items wrapper
2594
+ * @private
2595
+ */
2596
+ _resetCurrentItemsParent() {var _ref, _p$virtualWrapper;
2597
+ const p = this._p;
2598
+ p.currentItemsParent = (_ref = (_p$virtualWrapper = p.virtualWrapper) !== null && _p$virtualWrapper !== void 0 ? _p$virtualWrapper : p.userItemsParent) !== null && _ref !== void 0 ? _ref : p.list;
2599
+ }
2600
+
2601
+ /**
2602
+ * Destroy all created elements, for cleanup
2603
+ * @returns {VirtualListHelper}
2604
+ * @private
2605
+ */
2606
+ _destroyElements() {
2607
+ const p = this._p;
2608
+ const onItemUnrender = p.onItemUnrender;
2609
+ const existingEls = p.existingEls;
2610
+
2611
+ for (let i = 0; i < existingEls.length; i++) {
2612
+ const el = existingEls[i];
2613
+
2614
+ let parent = el.parentNode;
2615
+ if (parent)
2616
+ parent.removeChild(el);
2617
+ if (onItemUnrender && el[ItemIndexSymbol] !== undefined)
2618
+ onItemUnrender(el);
2619
+ }
2620
+
2621
+ existingEls.length = 0;
2622
+
2623
+ if (p.virtualWrapper) {
2624
+ if (p.virtualWrapper !== p.userItemsParent) {
2625
+ if (p.virtualWrapper.parentNode) {
2626
+ p.virtualWrapper.parentNode.removeChild(p.virtualWrapper);
2627
+ }
2628
+ }
2629
+ p.virtualWrapper = null;
2630
+ this._resetCurrentItemsParent();
2631
+ }
2632
+
2633
+ return this;
2634
+ }
2635
+
2636
+ /**
2637
+ * Marks (an) item(s) at specific index(es) as to be re-rendered. <br />
2638
+ * Applicable for virtual mode only.
2639
+ * @param {number} index
2640
+ * @param {number} count
2641
+ * @private
2642
+ */
2643
+ _invalidateItemIndexesAt(index, count) {
2644
+ const p = this._p;
2645
+
2646
+ this._setItemPositionsNeedsUpdate(index);
2647
+
2648
+ let existingEls = p.existingEls;
2649
+ let existingCount = existingEls.length;
2650
+ let existingRange = this._getExistingElsRange();
2651
+
2652
+ if (existingRange.firstValidArrayIndex === -1)
2653
+ return;
2654
+
2655
+ if (count === -1)
2656
+ count = existingEls.length;
2657
+
2658
+ // Clean
2659
+ if (index >= existingRange.firstIndex && index <= existingRange.lastIndex) {
2660
+ for (let i = existingRange.firstValidArrayIndex + index - existingRange.firstIndex,
2661
+ c = 0;
2662
+ i < existingCount && c < count;
2663
+ i++, c++)
2664
+ delete existingEls[i][ItemIndexSymbol];
2665
+ }
2666
+ }
2667
+
2668
+ /**
2669
+ * In/decrement the item-index marker for specific item(s). <br />
2670
+ * Used for inserting/removing items in the middle of the list, without re-rendering everything. <br />
2671
+ * Applicable for non-virtual mode only.
2672
+ * @param {number} index
2673
+ * @param {number} count
2674
+ * @private
2675
+ */
2676
+ _pushItemIndexesAt(index, count) {
2677
+ const p = this._p;
2678
+
2679
+ let existingEls = p.existingEls;
2680
+ let existingCount = existingEls.length;
2681
+ let existingRange = this._getExistingElsRange();
2682
+
2683
+ if (existingRange.firstValidArrayIndex === -1)
2684
+ return;
2685
+
2686
+ // Clean
2687
+ if (index >= existingRange.firstIndex && index <= existingRange.lastIndex) {
2688
+ for (let i = existingRange.firstValidArrayIndex + index - existingRange.firstIndex;
2689
+ i < existingCount;
2690
+ i++)
2691
+ existingEls[i][ItemIndexSymbol] += count;
2692
+ }
2693
+ }
2694
+
2695
+ /**
2696
+ * Hook relevant events
2697
+ * @returns {VirtualListHelper}
2698
+ * @private
2699
+ */
2700
+ _hookEvents() {
2701
+ const p = this._p;
2702
+
2703
+ this._unhookEvents();
2704
+
2705
+ if (p.virtual && p.hookScrollEvent) {
2706
+ p.list && p.list.addEventListener('scroll', /**@type Function*/p.boundRender);
2707
+ }
2708
+
2709
+ return this;
2710
+ }
2711
+
2712
+ /**
2713
+ * Unhook previously hooked events
2714
+ * @returns {VirtualListHelper}
2715
+ * @private
2716
+ */
2717
+ _unhookEvents() {
2718
+ const p = this._p;
2719
+
2720
+ p.list && p.list.removeEventListener('scroll', /**@type Function*/p.boundRender);
2721
+
2722
+ return this;
2723
+ }
2724
+
2725
+ /**
2726
+ * Mark item index from which the positions are not considered valid anymore. <br />
2727
+ * Applicable for virtual mode only.
2728
+ * @param {number} value
2729
+ * @private
2730
+ */
2731
+ _setItemPositionsNeedsUpdate(value) {
2732
+ const p = this._p;
2733
+
2734
+ if (value < p.itemPositionsNeedsUpdate) {
2735
+ p.itemPositionsNeedsUpdate = value;
2736
+ }
2737
+ }
2738
+
2739
+ /**
2740
+ * Calculates an item's top position (and stores in the private `cachedItemPositions` array). <br />
2741
+ * Allows calculating last+1 index too, to get the bottom-most position. <br />
2742
+ * Applicable for non-virtual mode only.
2743
+ * @param {number} index
2744
+ * @returns {number|undefined}
2745
+ * @private
2746
+ */
2747
+ _calculateItemPosition(index) {
2748
+ const p = this._p;
2749
+
2750
+ const cachedItemPositions = p.cachedItemPositions;
2751
+
2752
+ if (index >= p.itemPositionsNeedsUpdate) {
2753
+ const count = p.count;
2754
+ const cachedItemHeights = p.cachedItemHeights;
2755
+ const cachedItemEstimatedHeights = p.cachedItemEstimatedHeights;
2756
+ const estimatedItemHeight = p.estimatedItemHeight;
2757
+ const itemHeightEstimatorFn = p.itemHeightEstimatorFn;
2758
+
2759
+ if (cachedItemHeights.length !== count) {
2760
+ cachedItemHeights.length = count;
2761
+ cachedItemEstimatedHeights.length = count;
2762
+ cachedItemPositions.length = count;
2763
+ }
2764
+
2765
+ let fromIndex = p.itemPositionsNeedsUpdate;
2766
+ let toIndex = Math.min(index, count);
2767
+
2768
+ let pos = 0;
2769
+
2770
+ if (fromIndex > 0) {
2771
+ pos = cachedItemPositions[fromIndex - 1];
2772
+ }
2773
+
2774
+ for (let i = fromIndex; i <= toIndex; i++) {
2775
+ if (i === 0) {
2776
+ cachedItemPositions[i] = pos;
2777
+ continue;
2778
+ }
2779
+
2780
+ const prevIndex = i - 1;
2781
+
2782
+ let height = cachedItemHeights[prevIndex]; // already calculated
2783
+
2784
+ if (height === undefined) {
2785
+ height = itemHeightEstimatorFn ? itemHeightEstimatorFn(prevIndex) : null; // estimated per item
2786
+
2787
+ if (typeof height !== 'number')
2788
+ height = estimatedItemHeight; // estimated
2789
+
2790
+ cachedItemEstimatedHeights[prevIndex] = height;
2791
+ }
2792
+
2793
+ pos += height;
2794
+ cachedItemPositions[i] = pos;
2795
+ }
2796
+
2797
+ p.itemPositionsNeedsUpdate = toIndex + 1;
2798
+ }
2799
+
2800
+ // item after the last (calculate full height)
2801
+ if (index > 0 && index === p.count) {
2802
+ let height = p.cachedItemHeights[index - 1]; // already calculated
2803
+
2804
+ if (height === undefined) {
2805
+ height = p.itemHeightEstimatorFn ? p.itemHeightEstimatorFn(index - 1) : null; // estimated per item
2806
+
2807
+ if (typeof height !== 'number')
2808
+ height = p.estimatedItemHeight; // estimated
2809
+
2810
+ p.cachedItemEstimatedHeights[index - 1] = height;
2811
+ }
2812
+
2813
+ return cachedItemPositions[index - 1] + height;
2814
+ }
2815
+
2816
+ return cachedItemPositions[index];
2817
+ }
2818
+
2819
+ /**
2820
+ * Create (or reuse an existing) element for an item at the specified index,
2821
+ * and insert physically at specified position. <br />
2822
+ * This will also update the element's position in the `existingEls` array.
2823
+ * @param {Element|undefined} itemEl
2824
+ * @param {number} index
2825
+ * @param {Node|boolean|undefined} insertBefore
2826
+ * @returns {Element}
2827
+ * @private
2828
+ */
2829
+ _dequeueElementForIndex(itemEl, index, insertBefore) {
2830
+ const p = this._p;
2831
+ const virtualWrapper = p.virtualWrapper;
2832
+ const itemParent = p.currentItemsParent;
2833
+ const existingEls = p.existingEls;
2834
+ const onItemRender = p.onItemRender;
2835
+ const onItemUnrender = p.onItemUnrender;
2836
+ const isNew = !itemEl;
2837
+ const shouldReRender = isNew || index !== itemEl[ItemIndexSymbol];
2838
+
2839
+ if (itemEl) {
2840
+ if (onItemUnrender && shouldReRender) {
2841
+ onItemUnrender(itemEl);
2842
+ }
2843
+ } else {
2844
+ itemEl = p.itemElementCreatorFn();
2845
+
2846
+ if (virtualWrapper && insertBefore !== false) {
2847
+ /**@type ElementCSSInlineStyle*/itemEl.style.position = 'absolute';
2848
+ /**@type ElementCSSInlineStyle*/itemEl.style.top = '0';
2849
+ /**@type ElementCSSInlineStyle*/itemEl.style.left = '0';
2850
+ /**@type ElementCSSInlineStyle*/itemEl.style.right = '0';
2851
+ }
2852
+ }
2853
+
2854
+ // Render only if it's a new item element
2855
+ // OR the index of the existing element is not the same of the index to render
2856
+ if (shouldReRender) {
2857
+ itemEl.innerHTML = ''; // Basic cleanup
2858
+
2859
+ if (onItemRender)
2860
+ onItemRender(itemEl, index);
2861
+ }
2862
+
2863
+ if (insertBefore !== false) {
2864
+ if (!(insertBefore instanceof Node))
2865
+ insertBefore = null;
2866
+
2867
+ // Insert into DOM
2868
+ if (itemEl.parentNode !== itemParent ||
2869
+ itemEl.nextSibling !== insertBefore) {
2870
+ itemParent.insertBefore(itemEl, insertBefore);
2871
+ }
2872
+
2873
+ // Remove from existing list
2874
+ if (!isNew) {
2875
+ let i = existingEls.indexOf(itemEl);
2876
+ if (i !== -1)
2877
+ existingEls.splice(i, 1);
2878
+ }
2879
+
2880
+ // Insert into existing list
2881
+ let beforeIndex = insertBefore ? existingEls.indexOf( /**@type Element*/insertBefore) : -1;
2882
+ if (beforeIndex === -1) {
2883
+ existingEls.push(itemEl);
2884
+ } else {
2885
+ existingEls.splice(beforeIndex, 0, itemEl);
2886
+ }
2887
+
2888
+ if (virtualWrapper) {
2889
+ // Calculate height
2890
+ let itemHeight = itemEl.getBoundingClientRect().height;
2891
+
2892
+ // Put calculated height into cache, and invalidate positions if it's different
2893
+ let cachedItemHeight = p.cachedItemHeights[index];
2894
+ if (cachedItemHeight !== itemHeight) {
2895
+ p.cachedItemHeights[index] = itemHeight;
2896
+ }
2897
+
2898
+ if (cachedItemHeight !== undefined && itemHeight !== cachedItemHeight ||
2899
+ cachedItemHeight === undefined && itemHeight !== p.cachedItemEstimatedHeights[index]) {
2900
+ this._setItemPositionsNeedsUpdate(index + 1);
2901
+ }
2902
+
2903
+ // Set item top position
2904
+ let pos = this._calculateItemPosition(index);
2905
+ const supportedTransform = getSupportedTransform();
2906
+
2907
+ if (supportedTransform === false) {
2908
+ /**@type ElementCSSInlineStyle*/itemEl.style.top = `${pos}px`;
2909
+ } else {
2910
+ /**@type ElementCSSInlineStyle*/itemEl.style[supportedTransform] = `translateY(${pos}px)`;
2911
+ }
2912
+ }
2913
+ }
2914
+
2915
+ // Add index metadata to item
2916
+ itemEl[ItemIndexSymbol] = index;
2917
+
2918
+ return itemEl;
2919
+ }
2920
+
2921
+ /**
2922
+ * Fetches valid range of existingEls
2923
+ * @returns {{firstIndex: (*|number), firstValidArrayIndex: number, lastValidArrayIndex: number, lastIndex: (*|number)}}
2924
+ * @private
2925
+ */
2926
+ _getExistingElsRange() {
2927
+ const p = this._p,existingEls = p.existingEls;
2928
+
2929
+ let firstValidArrayIndex = -1,lastValidArrayIndex = -1;
2930
+
2931
+ for (let i = 0, len = existingEls.length; i < len; i++) {
2932
+ if (false === hasOwnProperty$1.call(existingEls[i], ItemIndexSymbol))
2933
+ continue;
2934
+ firstValidArrayIndex = i;
2935
+ break;
2936
+ }
2937
+
2938
+ for (let i = existingEls.length - 1; i >= 0; i--) {
2939
+ if (false === hasOwnProperty$1.call(existingEls[i], ItemIndexSymbol))
2940
+ continue;
2941
+ lastValidArrayIndex = i;
2942
+ break;
2943
+ }
2944
+
2945
+ let firstIndex = firstValidArrayIndex !== -1 ? existingEls[firstValidArrayIndex][ItemIndexSymbol] : -1;
2946
+ let lastIndex = lastValidArrayIndex !== -1 ? existingEls[lastValidArrayIndex][ItemIndexSymbol] : -1;
2947
+
2948
+ return {
2949
+ firstValidArrayIndex: firstValidArrayIndex,
2950
+ lastValidArrayIndex: lastValidArrayIndex,
2951
+ firstIndex: firstIndex,
2952
+ lastIndex: lastIndex
2953
+ };
2954
+ }
2955
+ }
2956
+
2957
+ /** Marks the item index associated with an item element */
2958
+ const ItemIndexSymbol = Symbol('index');
2959
+
2960
+ /** Marks an element for reuse */
2961
+ const ReuseElSymbol = Symbol('reuse');
2962
+
2963
+ /**
2964
+ * The default element creator
2965
+ * @returns {HTMLLIElement}
2966
+ */
2967
+ const defaultElementCreator = () => {
2968
+ return document.createElement('li');
2969
+ };
2970
+
2971
+ /**
2972
+ * Will look for the index in the `positions` array closest to the specified `pos` value (<= pos).
2973
+ * @param {number[]} positions
2974
+ * @param {number} pos
2975
+ * @param {number} [start=0]
2976
+ * @param {number} [end=-1]
2977
+ * @returns {number}
2978
+ */
2979
+ const binarySearchPosition = (positions, pos, start = 0, end = -1) => {
2980
+ let total = positions.length;
2981
+ if (end < 0)
2982
+ end += total;
2983
+ if (end <= start) return end; // 0 or 1 length array
2984
+
2985
+ while (start <= end) {
2986
+ let mid = Math.floor(start + (end - start) / 2);
2987
+ let midPos = positions[mid];
2988
+
2989
+ if (midPos === pos || midPos <= pos && mid < total && positions[mid + 1] > pos) {
2990
+ while (mid > 0 && positions[mid - 1] === midPos) // avoid bugs on 0-height items
2991
+ mid--;
2992
+
2993
+ return mid;
2994
+ }
2995
+
2996
+ if (midPos < pos)
2997
+ start = mid + 1;else
2998
+
2999
+ end = mid - 1;
3000
+ }
3001
+
3002
+ return end === -1 ? 0 : total - 1;
3003
+ };
3004
+
3005
+ /**
3006
+ * Will look for the index in a virtual list of positions supplied by `total` and `fn`,
3007
+ * closest to the specified `pos` value (<= pos).
3008
+ * @param {number} total
3009
+ * @param {function(index: number):number} fn
3010
+ * @param {number} pos
3011
+ * @param {number} [start=0]
3012
+ * @param {number} [end=-1]
3013
+ * @returns {number}
3014
+ */
3015
+ const binarySearchPositionByFn = (total, fn, pos, start = 0, end = -1) => {
3016
+ if (end < 0)
3017
+ end += total;
3018
+ if (end <= start) return end; // 0 or 1 length array
3019
+
3020
+ while (start <= end) {
3021
+ let mid = Math.floor(start + (end - start) / 2);
3022
+ let midPos = fn(mid);
3023
+
3024
+ if (midPos === pos || midPos <= pos && mid < total && fn(mid + 1) > pos) {
3025
+ while (mid > 0 && fn(mid - 1) === midPos) // avoid bugs on 0-height items
3026
+ mid--;
3027
+
3028
+ return mid;
3029
+ }
3030
+
3031
+ if (midPos < pos)
3032
+ start = mid + 1;else
3033
+
3034
+ end = mid - 1;
3035
+ }
3036
+
3037
+ return end === -1 ? 0 : fn(total - 1);
3038
+ };
3039
+
3040
+ /**
3041
+ * Finds the last item in the array for which `fn` returns a truthy value
3042
+ * @param {Array} array
3043
+ * @param {Function} fn
3044
+ * @returns {undefined|*}
3045
+ */
3046
+ const findLast = (array, fn) => {
3047
+ for (let i = array.length - 1; i >= 0; i--) {
3048
+ if (fn(array[i])) {
3049
+ return array[i];
3050
+ }
3051
+ }
3052
+ return undefined;
3053
+ };
3054
+
3055
+ let _isTransformSupported = null;
3056
+
3057
+ const getSupportedTransform = () => {
3058
+ if (_isTransformSupported === null) {
3059
+ let prefixes = ['transform', 'WebkitTransform', 'MozTransform', 'OTransform', 'msTransform'];
3060
+ let div = document.createElement('div');
3061
+ _isTransformSupported = false;
3062
+ for (let item of prefixes) {
3063
+ if (div && div.style[item] !== undefined) {
3064
+ _isTransformSupported = item;
3065
+ break;
3066
+ }
3067
+ }
1713
3068
  }
1714
- }
3069
+ return _isTransformSupported;
3070
+ };
1715
3071
 
1716
3072
  function ByColumnFilter(row, args) {
1717
3073
 
@@ -1746,7 +3102,10 @@ let hasIeDragAndDropBug = ieVersion && ieVersion < 10;
1746
3102
  let createElement = document.createElement.bind(document);
1747
3103
  const hasOwnProperty = Object.prototype.hasOwnProperty;
1748
3104
 
1749
- const IsSafeSymbol = 'safe';
3105
+ const IsSafeSymbol = Symbol('safe');
3106
+ const HoverInEventSymbol = Symbol('hover_in');
3107
+ const HoverOutEventSymbol = Symbol('hover_out');
3108
+ const RowClickEventSymbol = Symbol('row_click');
1750
3109
 
1751
3110
  function webkitRenderBugfix(el) {
1752
3111
  // BUGFIX: WebKit has a bug where it does not relayout, and this affects us because scrollbars
@@ -1839,9 +3198,7 @@ DGTable.prototype.initialize = function (options) {
1839
3198
  data('dgtable', that);
1840
3199
 
1841
3200
  // For jQuery.UI or jquery.removeevent
1842
- $el.on('remove', function () {
1843
- that.destroy();
1844
- });
3201
+ $el.on('remove', () => that.destroy());
1845
3202
 
1846
3203
  p.onMouseMoveResizeAreaBound = this._onMouseMoveResizeArea.bind(this);
1847
3204
  p.onEndDragColumnHeaderBound = this._onEndDragColumnHeader.bind(this);
@@ -1851,92 +3208,97 @@ DGTable.prototype.initialize = function (options) {
1851
3208
 
1852
3209
  /**
1853
3210
  * @private
1854
- * @field {Boolean} _tableSkeletonNeedsRendering */
3211
+ * @field {boolean} _tableSkeletonNeedsRendering */
1855
3212
  p.tableSkeletonNeedsRendering = true;
1856
3213
 
1857
3214
  /**
1858
3215
  * @private
1859
- * @field {Boolean} virtualTable */
3216
+ * @field {boolean} virtualTable */
1860
3217
  o.virtualTable = options.virtualTable === undefined ? true : !!options.virtualTable;
1861
3218
 
1862
3219
  /**
1863
3220
  * @private
1864
- * @field {Number} rowsBufferSize */
3221
+ * @field {number} estimatedRowHeight */
3222
+ o.estimatedRowHeight = options.estimatedRowHeight === undefined ? 40 : options.estimatedRowHeight;
3223
+
3224
+ /**
3225
+ * @private
3226
+ * @field {number} rowsBufferSize */
1865
3227
  o.rowsBufferSize = options.rowsBufferSize || 3;
1866
3228
 
1867
3229
  /**
1868
3230
  * @private
1869
- * @field {Number} minColumnWidth */
3231
+ * @field {number} minColumnWidth */
1870
3232
  o.minColumnWidth = Math.max(options.minColumnWidth || 35, 0);
1871
3233
 
1872
3234
  /**
1873
3235
  * @private
1874
- * @field {Number} resizeAreaWidth */
3236
+ * @field {number} resizeAreaWidth */
1875
3237
  o.resizeAreaWidth = options.resizeAreaWidth || 8;
1876
3238
 
1877
3239
  /**
1878
3240
  * @private
1879
- * @field {Boolean} resizableColumns */
3241
+ * @field {boolean} resizableColumns */
1880
3242
  o.resizableColumns = options.resizableColumns === undefined ? true : !!options.resizableColumns;
1881
3243
 
1882
3244
  /**
1883
3245
  * @private
1884
- * @field {Boolean} movableColumns */
3246
+ * @field {boolean} movableColumns */
1885
3247
  o.movableColumns = options.movableColumns === undefined ? true : !!options.movableColumns;
1886
3248
 
1887
3249
  /**
1888
3250
  * @private
1889
- * @field {Number} sortableColumns */
3251
+ * @field {number} sortableColumns */
1890
3252
  o.sortableColumns = options.sortableColumns === undefined ? 1 : parseInt(options.sortableColumns, 10) || 1;
1891
3253
 
1892
3254
  /**
1893
3255
  * @private
1894
- * @field {Boolean} adjustColumnWidthForSortArrow */
3256
+ * @field {boolean} adjustColumnWidthForSortArrow */
1895
3257
  o.adjustColumnWidthForSortArrow = options.adjustColumnWidthForSortArrow === undefined ? true : !!options.adjustColumnWidthForSortArrow;
1896
3258
 
1897
3259
  /**
1898
3260
  * @private
1899
- * @field {Boolean} convertColumnWidthsToRelative */
3261
+ * @field {boolean} convertColumnWidthsToRelative */
1900
3262
  o.convertColumnWidthsToRelative = options.convertColumnWidthsToRelative === undefined ? false : !!options.convertColumnWidthsToRelative;
1901
3263
 
1902
3264
  /**
1903
3265
  * @private
1904
- * @field {Boolean} autoFillTableWidth */
3266
+ * @field {boolean} autoFillTableWidth */
1905
3267
  o.autoFillTableWidth = options.autoFillTableWidth === undefined ? false : !!options.autoFillTableWidth;
1906
3268
 
1907
3269
  /**
1908
3270
  * @private
1909
- * @field {String} cellClasses */
3271
+ * @field {string} cellClasses */
1910
3272
  o.cellClasses = options.cellClasses === undefined ? '' : options.cellClasses;
1911
3273
 
1912
3274
  /**
1913
3275
  * @private
1914
- * @field {String} resizerClassName */
3276
+ * @field {string} resizerClassName */
1915
3277
  o.resizerClassName = options.resizerClassName === undefined ? 'dgtable-resize' : options.resizerClassName;
1916
3278
 
1917
3279
  /**
1918
3280
  * @private
1919
- * @field {String} tableClassName */
3281
+ * @field {string} tableClassName */
1920
3282
  o.tableClassName = options.tableClassName === undefined ? 'dgtable' : options.tableClassName;
1921
3283
 
1922
3284
  /**
1923
3285
  * @private
1924
- * @field {Boolean} allowCellPreview */
3286
+ * @field {boolean} allowCellPreview */
1925
3287
  o.allowCellPreview = options.allowCellPreview === undefined ? true : options.allowCellPreview;
1926
3288
 
1927
3289
  /**
1928
3290
  * @private
1929
- * @field {Boolean} allowHeaderCellPreview */
3291
+ * @field {boolean} allowHeaderCellPreview */
1930
3292
  o.allowHeaderCellPreview = options.allowHeaderCellPreview === undefined ? true : options.allowHeaderCellPreview;
1931
3293
 
1932
3294
  /**
1933
3295
  * @private
1934
- * @field {String} cellPreviewClassName */
3296
+ * @field {string} cellPreviewClassName */
1935
3297
  o.cellPreviewClassName = options.cellPreviewClassName === undefined ? 'dgtable-cell-preview' : options.cellPreviewClassName;
1936
3298
 
1937
3299
  /**
1938
3300
  * @private
1939
- * @field {Boolean} cellPreviewAutoBackground */
3301
+ * @field {boolean} cellPreviewAutoBackground */
1940
3302
  o.cellPreviewAutoBackground = options.cellPreviewAutoBackground === undefined ? true : options.cellPreviewAutoBackground;
1941
3303
 
1942
3304
  /**
@@ -1949,17 +3311,17 @@ DGTable.prototype.initialize = function (options) {
1949
3311
 
1950
3312
  /**
1951
3313
  * @private
1952
- * @field {Boolean} width */
3314
+ * @field {boolean} width */
1953
3315
  o.width = options.width === undefined ? DGTable.Width.NONE : options.width;
1954
3316
 
1955
3317
  /**
1956
3318
  * @private
1957
- * @field {Boolean} relativeWidthGrowsToFillWidth */
3319
+ * @field {boolean} relativeWidthGrowsToFillWidth */
1958
3320
  o.relativeWidthGrowsToFillWidth = options.relativeWidthGrowsToFillWidth === undefined ? true : !!options.relativeWidthGrowsToFillWidth;
1959
3321
 
1960
3322
  /**
1961
3323
  * @private
1962
- * @field {Boolean} relativeWidthShrinksToFillWidth */
3324
+ * @field {boolean} relativeWidthShrinksToFillWidth */
1963
3325
  o.relativeWidthShrinksToFillWidth = options.relativeWidthShrinksToFillWidth === undefined ? false : !!options.relativeWidthShrinksToFillWidth;
1964
3326
 
1965
3327
  this.setCellFormatter(options.cellFormatter);
@@ -1967,7 +3329,7 @@ DGTable.prototype.initialize = function (options) {
1967
3329
  this.setFilter(options.filter);
1968
3330
 
1969
3331
  /** @private
1970
- * @field {Number} height */
3332
+ * @field {number} height */
1971
3333
  o.height = options.height;
1972
3334
 
1973
3335
  // Prepare columns
@@ -2014,6 +3376,12 @@ DGTable.prototype.initialize = function (options) {
2014
3376
  * @field {RowCollection} _filteredRows */
2015
3377
  p.filteredRows = null;
2016
3378
 
3379
+ this._setupHovers();
3380
+ };
3381
+
3382
+ DGTable.prototype._setupHovers = function () {
3383
+ const that = this,p = that.p;
3384
+
2017
3385
  /*
2018
3386
  Setup hover mechanism.
2019
3387
  We need this to be high performance, as there may be MANY cells to call this on, on creation and destruction.
@@ -2021,12 +3389,11 @@ DGTable.prototype.initialize = function (options) {
2021
3389
  */
2022
3390
 
2023
3391
  /**
2024
- * @param {MouseEvent} evt
3392
+ * @param {MouseEvent} event
2025
3393
  * @this {HTMLElement}
2026
3394
  * */
2027
- let hoverMouseOverHandler = function (evt) {
2028
- evt = evt || event;
2029
- let relatedTarget = evt.fromElement || evt.relatedTarget;
3395
+ let hoverMouseOverHandler = function (event) {
3396
+ let relatedTarget = event.fromElement || event.relatedTarget;
2030
3397
  if (relatedTarget === this || $.contains(this, relatedTarget)) return;
2031
3398
  if (this['__previewCell'] && (relatedTarget === this['__previewCell'] || $.contains(this['__previewCell'], relatedTarget))) return;
2032
3399
  that._cellMouseOverEvent.call(that, this);
@@ -2044,100 +3411,141 @@ DGTable.prototype.initialize = function (options) {
2044
3411
  that._cellMouseOutEvent.call(that, this);
2045
3412
  };
2046
3413
 
2047
- if ('addEventListener' in window) {
3414
+ /**
3415
+ * @param {HTMLElement} el cell or header-cell
3416
+ * */
3417
+ p._bindCellHoverIn = function (el) {
3418
+ if (!el[HoverInEventSymbol]) {
3419
+ el.addEventListener('mouseover', el[HoverInEventSymbol] = hoverMouseOverHandler.bind(el));
3420
+ }
3421
+ };
2048
3422
 
2049
- /**
2050
- * @param {HTMLElement} el cell or header-cell
2051
- * */
2052
- p._bindCellHoverIn = function (el) {
2053
- if (!el['__hoverIn']) {
2054
- el.addEventListener('mouseover', el['__hoverIn'] = hoverMouseOverHandler.bind(el));
2055
- }
2056
- };
3423
+ /**
3424
+ * @param {HTMLElement} el cell or header-cell
3425
+ * */
3426
+ p._unbindCellHoverIn = function (el) {
3427
+ if (el[HoverInEventSymbol]) {
3428
+ el.removeEventListener('mouseover', el[HoverInEventSymbol]);
3429
+ el[HoverInEventSymbol] = null;
3430
+ }
3431
+ };
2057
3432
 
2058
- /**
2059
- * @param {HTMLElement} el cell or header-cell
2060
- * */
2061
- p._unbindCellHoverIn = function (el) {
2062
- if (el['__hoverIn']) {
2063
- el.removeEventListener('mouseover', el['__hoverIn']);
2064
- el['__hoverIn'] = null;
2065
- }
2066
- };
3433
+ /**
3434
+ * @param {HTMLElement} el cell or header-cell
3435
+ * @returns {DGTable} self
3436
+ * */
3437
+ p._bindCellHoverOut = function (el) {
3438
+ if (!el[HoverOutEventSymbol]) {
3439
+ el.addEventListener('mouseout', el[HoverOutEventSymbol] = hoverMouseOutHandler.bind(el['__cell'] || el));
3440
+ }
3441
+ return this;
3442
+ };
2067
3443
 
2068
- /**
2069
- * @param {HTMLElement} el cell or header-cell
2070
- * @returns {DGTable} self
2071
- * */
2072
- p._bindCellHoverOut = function (el) {
2073
- if (!el['__hoverOut']) {
2074
- el.addEventListener('mouseout', el['__hoverOut'] = hoverMouseOutHandler.bind(el['__cell'] || el));
2075
- }
2076
- return this;
2077
- };
3444
+ /**
3445
+ * @param {HTMLElement} el cell or header-cell
3446
+ * @returns {DGTable} self
3447
+ * */
3448
+ p._unbindCellHoverOut = function (el) {
3449
+ if (el[HoverOutEventSymbol]) {
3450
+ el.removeEventListener('mouseout', el[HoverOutEventSymbol]);
3451
+ el[HoverOutEventSymbol] = null;
3452
+ }
3453
+ return this;
3454
+ };
3455
+ };
2078
3456
 
2079
- /**
2080
- * @param {HTMLElement} el cell or header-cell
2081
- * @returns {DGTable} self
2082
- * */
2083
- p._unbindCellHoverOut = function (el) {
2084
- if (el['__hoverOut']) {
2085
- el.removeEventListener('mouseout', el['__hoverOut']);
2086
- el['__hoverOut'] = null;
2087
- }
2088
- return this;
2089
- };
3457
+ DGTable.prototype._setupVirtualTable = function () {
3458
+ const that = this,p = that.p,o = that.o;
2090
3459
 
2091
- } else {
3460
+ const tableClassName = o.tableClassName,
3461
+ rowClassName = tableClassName + '-row',
3462
+ altRowClassName = tableClassName + '-row-alt',
3463
+ cellClassName = tableClassName + '-cell';
2092
3464
 
2093
- /**
2094
- * @param {HTMLElement} el cell or header-cell
2095
- * */
2096
- p._bindCellHoverIn = function (el) {
2097
- if (!el['__hoverIn']) {
2098
- el.attachEvent('mouseover', el['__hoverIn'] = hoverMouseOverHandler.bind(el));
2099
- }
2100
- };
3465
+ let visibleColumns = p.visibleColumns,
3466
+ colCount = visibleColumns.length;
2101
3467
 
2102
- /**
2103
- * @param {HTMLElement} el cell or header-cell
2104
- * */
2105
- p._unbindCellHoverIn = function (el) {
2106
- if (el['__hoverIn']) {
2107
- el.detachEvent('mouseover', el['__hoverIn']);
2108
- el['__hoverIn'] = null;
2109
- }
2110
- };
3468
+ p.notifyRendererOfColumnsConfig = () => {
3469
+ visibleColumns = p.visibleColumns;
3470
+ colCount = visibleColumns.length;
3471
+
3472
+ for (let colIndex = 0, column; colIndex < colCount; colIndex++) {
3473
+ column = visibleColumns[colIndex];
3474
+ column._finalWidth = column.actualWidthConsideringScrollbarWidth || column.actualWidth;
3475
+ }
3476
+ };
3477
+
3478
+ p.virtualListHelper = new VirtualListHelper({
3479
+ list: p.table,
3480
+ itemsParent: p.tbody,
3481
+ autoVirtualWrapperWidth: false,
3482
+ virtual: true,
3483
+ buffer: o.rowsBufferSize,
3484
+ estimatedItemHeight: o.estimatedRowHeight || 40,
3485
+ itemElementCreatorFn: () => {
3486
+ return createElement('div');
3487
+ },
3488
+ onItemRender: (row, index) => {
3489
+ const rows = p.filteredRows || p.rows,
3490
+ isDataFiltered = !!p.filteredRows,
3491
+ allowCellPreview = p.allowCellPreview;
3492
+
3493
+ row.className = rowClassName;
3494
+ if (index % 2 === 1)
3495
+ row.className += ' ' + altRowClassName;
3496
+
3497
+ let rowData = rows[index];
3498
+ let physicalRowIndex = isDataFiltered ? rowData['__i'] : index;
3499
+
3500
+ row['rowIndex'] = index;
3501
+ row['physicalRowIndex'] = physicalRowIndex;
3502
+
3503
+ for (let colIndex = 0; colIndex < colCount; colIndex++) {
3504
+ let column = visibleColumns[colIndex];
3505
+ let cell = createElement('div');
3506
+ cell['columnName'] = column.name;
3507
+ cell.setAttribute('data-column', column.name);
3508
+ cell.className = cellClassName;
3509
+ cell.style.width = column._finalWidth + 'px';
3510
+ if (column.cellClasses) cell.className += ' ' + column.cellClasses;
3511
+ if (allowCellPreview) {
3512
+ p._bindCellHoverIn(cell);
3513
+ }
3514
+
3515
+ let cellInner = cell.appendChild(createElement('div'));
3516
+ cellInner.innerHTML = this._getHtmlForCell(rowData, column);
2111
3517
 
2112
- /**
2113
- * @param {HTMLElement} el cell or header-cell
2114
- * */
2115
- p._bindCellHoverOut = function (el) {
2116
- if (!el['__hoverOut']) {
2117
- el.attachEvent('mouseout', el['__hoverOut'] = hoverMouseOutHandler.bind(el['__cell'] || el));
3518
+ row.appendChild(cell);
2118
3519
  }
2119
- };
2120
3520
 
2121
- /**
2122
- * @param {HTMLElement} el cell or header-cell
2123
- * @returns {DGTable} self
2124
- * */
2125
- p._unbindCellHoverOut = function (el) {
2126
- if (el['__hoverOut']) {
2127
- el.detachEvent('mouseout', el['__hoverOut']);
2128
- el['__hoverOut'] = null;
3521
+ row.addEventListener('click', row[RowClickEventSymbol] = (event) => {
3522
+ that.trigger('rowclick', event, index, physicalRowIndex, row, rowData);
3523
+ });
3524
+
3525
+ that.trigger('rowcreate', index, physicalRowIndex, row, rowData);
3526
+ },
3527
+
3528
+ onItemUnrender: (row) => {
3529
+ if (row[RowClickEventSymbol]) {
3530
+ row.removeEventListener('click', row[RowClickEventSymbol]);
2129
3531
  }
2130
- return this;
2131
- };
2132
3532
 
2133
- }
3533
+ that._unbindCellEventsForRow(row);
3534
+
3535
+ that.trigger('rowdestroy', row);
3536
+ }
3537
+ });
3538
+
3539
+ p.virtualListHelper.setCount(p.rows.length);
3540
+
3541
+ p.notifyRendererOfColumnsConfig();
2134
3542
  };
2135
3543
 
2136
3544
  /**
2137
3545
  * Add an event listener
2138
3546
  * @public
2139
3547
  * @expose
2140
- * @param {String} eventName
3548
+ * @param {string} eventName
2141
3549
  * @param {Function} callback
2142
3550
  * @returns {DGTable}
2143
3551
  */
@@ -2162,7 +3570,7 @@ DGTable.prototype.on = function (eventName, callback) {
2162
3570
  * Add an event listener for a one shot
2163
3571
  * @public
2164
3572
  * @expose
2165
- * @param {String} eventName
3573
+ * @param {string} eventName
2166
3574
  * @param {Function} callback
2167
3575
  * @returns {DGTable}
2168
3576
  */
@@ -2187,7 +3595,7 @@ DGTable.prototype.once = function (eventName, callback) {
2187
3595
  * Remove an event listener
2188
3596
  * @public
2189
3597
  * @expose
2190
- * @param {String} eventName
3598
+ * @param {string} eventName
2191
3599
  * @param {Function} callback
2192
3600
  * @returns {DGTable}
2193
3601
  */
@@ -2230,8 +3638,8 @@ DGTable.prototype.trigger = function (eventName) {
2230
3638
  /**
2231
3639
  * Detect column width mode
2232
3640
  * @private
2233
- * @param {Number|String} width
2234
- * @param {Number} minWidth
3641
+ * @param {Number|string} width
3642
+ * @param {number} minWidth
2235
3643
  * @returns {Object} parsed width
2236
3644
  */
2237
3645
  DGTable.prototype._parseColumnWidth = function (width, minWidth) {
@@ -2303,7 +3711,7 @@ DGTable.prototype._initColumnFromData = function (columnData) {
2303
3711
  * @public
2304
3712
  * @expose
2305
3713
  */
2306
- DGTable.prototype.close = DGTable.prototype.remove = DGTable.prototype.destroy = function () {
3714
+ DGTable.prototype.close = DGTable.prototype.remove = DGTable.prototype.destroy = function () {var _p$virtualListHelper;
2307
3715
 
2308
3716
  let that = this,
2309
3717
  p = that.p || {},
@@ -2318,16 +3726,15 @@ DGTable.prototype.close = DGTable.prototype.remove = DGTable.prototype.destroy =
2318
3726
  p.$resizer = null;
2319
3727
  }
2320
3728
 
2321
- if (p.$tbody) {
2322
- let trs = p.$tbody[0].childNodes;
2323
- for (let i = 0, len = trs.length; i < len; i++) {
2324
- that.trigger('rowdestroy', trs[i]);
2325
- }
2326
- }
3729
+ (_p$virtualListHelper = p.virtualListHelper) === null || _p$virtualListHelper === void 0 ? void 0 : _p$virtualListHelper.destroy();
3730
+ p.virtualListHelper = null;
2327
3731
 
2328
3732
  // Using quotes for __super__ because Google Closure Compiler has a bug...
2329
3733
 
2330
- this._destroyHeaderCells()._unbindCellEventsForTable();
3734
+ this._destroyHeaderCells();
3735
+
3736
+ p.virtualListHelper.destroy();
3737
+
2331
3738
  if (p.$table) {
2332
3739
  p.$table.empty();
2333
3740
  }
@@ -2381,12 +3788,6 @@ DGTable.prototype._unbindCellEventsForTable = function () {
2381
3788
  }
2382
3789
  }
2383
3790
 
2384
- if (p.tbody) {
2385
- for (let i = 0, rows = p.tbody.childNodes, rowCount = rows.length; i < rowCount; i++) {
2386
- this._unbindCellEventsForRow(rows[i]);
2387
- }
2388
- }
2389
-
2390
3791
  return this;
2391
3792
  };
2392
3793
 
@@ -2424,8 +3825,6 @@ DGTable.prototype.render = function () {
2424
3825
  return this;
2425
3826
  }
2426
3827
 
2427
- let renderedRows, rowCount;
2428
-
2429
3828
  if (p.tableSkeletonNeedsRendering === true) {
2430
3829
  p.tableSkeletonNeedsRendering = false;
2431
3830
 
@@ -2442,12 +3841,7 @@ DGTable.prototype.render = function () {
2442
3841
  tableWidthChanged(true, false) // Take this chance to calculate required column widths
2443
3842
  ._renderSkeletonHeaderCells();
2444
3843
 
2445
- if (!o.virtualTable) {
2446
- let rows = p.filteredRows || p.rows;
2447
- rowCount = rows.length;
2448
- renderedRows = this.renderRows(0, rowCount - 1);
2449
- p.$tbody.html('').append(renderedRows);
2450
- }
3844
+ p.virtualListHelper.invalidate();
2451
3845
 
2452
3846
  this._updateLastCellWidthFromScrollbar(true);
2453
3847
 
@@ -2472,63 +3866,10 @@ DGTable.prototype.render = function () {
2472
3866
  }
2473
3867
 
2474
3868
  this.trigger('renderskeleton');
3869
+ }
2475
3870
 
2476
- if (o.virtualTable) {
2477
- p.$table.on('scroll', this._onVirtualTableScrolled.bind(this));
2478
- this.render();
2479
- }
2480
-
2481
- } else if (o.virtualTable) {
2482
- rowCount = (p.filteredRows || p.rows).length;
2483
- let scrollTop = p.table.scrollTop;
2484
- let firstVisible = Math.floor((scrollTop - p.virtualRowHeightFirst) / p.virtualRowHeight) + 1 - o.rowsBufferSize;
2485
- let lastVisible = Math.ceil((scrollTop - p.virtualRowHeightFirst + p.visibleHeight) / p.virtualRowHeight) + o.rowsBufferSize;
2486
- if (firstVisible < 0) firstVisible = 0;
2487
- if (lastVisible >= rowCount) {
2488
- lastVisible = rowCount - 1;
2489
- }
2490
-
2491
- let oldFirstVisible = -1,oldLastVisible = -1;
2492
- let tbodyChildNodes = p.tbody.childNodes;
2493
- if (tbodyChildNodes.length) {
2494
- oldFirstVisible = tbodyChildNodes[0]['rowIndex'];
2495
- oldLastVisible = tbodyChildNodes[tbodyChildNodes.length - 1]['rowIndex'];
2496
- }
2497
-
2498
- let countToRemove;
2499
-
2500
- if (oldFirstVisible !== -1 && oldFirstVisible < firstVisible) {
2501
- countToRemove = Math.min(oldLastVisible + 1, firstVisible) - oldFirstVisible;
2502
- for (let i = 0; i < countToRemove; i++) {
2503
- this.trigger('rowdestroy', tbodyChildNodes[0]);
2504
- this._unbindCellEventsForRow(tbodyChildNodes[0]);
2505
- p.tbody.removeChild(tbodyChildNodes[0]);
2506
- }
2507
- oldFirstVisible += countToRemove;
2508
- if (oldFirstVisible > oldLastVisible) {
2509
- oldFirstVisible = oldLastVisible = -1;
2510
- }
2511
- } else if (oldLastVisible !== -1 && oldLastVisible > lastVisible) {
2512
- countToRemove = oldLastVisible - Math.max(oldFirstVisible - 1, lastVisible);
2513
- for (let i = 0; i < countToRemove; i++) {
2514
- this.trigger('rowdestroy', tbodyChildNodes[tbodyChildNodes.length - 1]);
2515
- this._unbindCellEventsForRow(tbodyChildNodes[tbodyChildNodes.length - 1]);
2516
- p.tbody.removeChild(tbodyChildNodes[tbodyChildNodes.length - 1]);
2517
- }
2518
- if (oldLastVisible < oldFirstVisible) {
2519
- oldFirstVisible = oldLastVisible = -1;
2520
- }
2521
- }
3871
+ p.virtualListHelper.render();
2522
3872
 
2523
- if (firstVisible < oldFirstVisible) {
2524
- renderedRows = this.renderRows(firstVisible, Math.min(lastVisible, oldFirstVisible - 1));
2525
- p.$tbody.prepend(renderedRows);
2526
- }
2527
- if (lastVisible > oldLastVisible || oldLastVisible === -1) {
2528
- renderedRows = this.renderRows(oldLastVisible === -1 ? firstVisible : oldLastVisible + 1, lastVisible);
2529
- p.$tbody.append(renderedRows);
2530
- }
2531
- }
2532
3873
  this.trigger('render');
2533
3874
  return this;
2534
3875
  };
@@ -2537,13 +3878,14 @@ DGTable.prototype.render = function () {
2537
3878
  * Forces a full render of the table
2538
3879
  * @public
2539
3880
  * @expose
2540
- * @param {Boolean=true} render - Should render now?
3881
+ * @param {boolean=true} render - Should render now?
2541
3882
  * @returns {DGTable} self
2542
3883
  */
2543
- DGTable.prototype.clearAndRender = function (render) {
3884
+ DGTable.prototype.clearAndRender = function (render) {var _p$notifyRendererOfCo;
2544
3885
  let p = this.p;
2545
3886
 
2546
3887
  p.tableSkeletonNeedsRendering = true;
3888
+ (_p$notifyRendererOfCo = p.notifyRendererOfColumnsConfig) === null || _p$notifyRendererOfCo === void 0 ? void 0 : _p$notifyRendererOfCo.call(p);
2547
3889
 
2548
3890
  if (render === undefined || render) {
2549
3891
  this.render();
@@ -2552,129 +3894,10 @@ DGTable.prototype.clearAndRender = function (render) {
2552
3894
  return this;
2553
3895
  };
2554
3896
 
2555
- /**
2556
- * Render rows
2557
- * @private
2558
- * @param {Number} first first row to render
2559
- * @param {Number} last last row to render
2560
- * @returns {DocumentFragment} fragment containing all rendered rows
2561
- */
2562
- DGTable.prototype.renderRows = function (first, last) {
2563
- const o = this.o,p = this.p;
2564
-
2565
- let tableClassName = o.tableClassName,
2566
- rowClassName = tableClassName + '-row',
2567
- altRowClassName = tableClassName + '-row-alt',
2568
- cellClassName = tableClassName + '-cell',
2569
- rows = p.filteredRows || p.rows,
2570
- isDataFiltered = !!p.filteredRows,
2571
- allowCellPreview = o.allowCellPreview,
2572
- visibleColumns = p.visibleColumns,
2573
- isVirtual = o.virtualTable,
2574
- virtualRowHeightFirst = p.virtualRowHeightFirst,
2575
- virtualRowHeight = p.virtualRowHeight,
2576
- top;
2577
-
2578
- let colCount = visibleColumns.length;
2579
- for (let colIndex = 0, column; colIndex < colCount; colIndex++) {
2580
- column = visibleColumns[colIndex];
2581
- column._finalWidth = column.actualWidthConsideringScrollbarWidth || column.actualWidth;
2582
- }
2583
-
2584
- let bodyFragment = document.createDocumentFragment();
2585
-
2586
- let isRtl = this._isTableRtl(),
2587
- virtualRowXAttr = isRtl ? 'right' : 'left';
2588
-
2589
- const supportedTransform = CssUtil.getSupportedTransform();
2590
-
2591
- for (let i = first, rowCount = rows.length;
2592
- i < rowCount && i <= last;
2593
- i++) {
2594
-
2595
- let rowData = rows[i];
2596
- let physicalRowIndex = isDataFiltered ? rowData['__i'] : i;
2597
-
2598
- let row = createElement('div');
2599
- row.className = rowClassName;
2600
- if (i % 2 === 1)
2601
- row.className += ' ' + altRowClassName;
2602
-
2603
- row['rowIndex'] = i;
2604
- row['physicalRowIndex'] = physicalRowIndex;
2605
-
2606
- for (let colIndex = 0; colIndex < colCount; colIndex++) {
2607
- let column = visibleColumns[colIndex];
2608
- let cell = createElement('div');
2609
- cell['columnName'] = column.name;
2610
- cell.setAttribute('data-column', column.name);
2611
- cell.className = cellClassName;
2612
- cell.style.width = column._finalWidth + 'px';
2613
- if (column.cellClasses) cell.className += ' ' + column.cellClasses;
2614
- if (allowCellPreview) {
2615
- p._bindCellHoverIn(cell);
2616
- }
2617
-
2618
- let cellInner = cell.appendChild(createElement('div'));
2619
- cellInner.innerHTML = this._getHtmlForCell(rowData, column);
2620
-
2621
- row.appendChild(cell);
2622
- }
2623
-
2624
- if (isVirtual) {
2625
- top = i > 0 ? virtualRowHeightFirst + (i - 1) * virtualRowHeight : 0;
2626
- row.style.position = 'absolute';
2627
- row.style[virtualRowXAttr] = 0;
2628
-
2629
- if (supportedTransform === false) {
2630
- row.style.top = `${top}px`;
2631
- } else {
2632
- row.style.top = '0px';
2633
- row.style[supportedTransform] = `translateY(${top}px)`;
2634
- }
2635
- }
2636
-
2637
- bodyFragment.appendChild(row);
2638
-
2639
- this.trigger('rowcreate', i, physicalRowIndex, row, rowData);
2640
-
2641
- let rowIndex = i;
2642
- row.addEventListener('click', (event) => {
2643
- this.trigger('rowclick', event, rowIndex, physicalRowIndex, row, rowData);
2644
- });
2645
- }
2646
-
2647
- return bodyFragment;
2648
- };
2649
-
2650
- /**
2651
- * Calculate virtual table height for scrollbar
2652
- * @private
2653
- * @returns {DGTable} self
2654
- */
2655
- DGTable.prototype._calculateVirtualHeight = function () {
2656
- let p = this.p;
2657
-
2658
- if (p.tbody) {
2659
- let rowCount = (p.filteredRows || p.rows).length;
2660
- let height = p.virtualRowHeight * rowCount;
2661
- if (rowCount) {
2662
- height += p.virtualRowHeightFirst - p.virtualRowHeight;
2663
- height += p.virtualRowHeightLast - p.virtualRowHeight;
2664
- }
2665
- // At least 1 pixel - to show scrollers correctly.
2666
- if (height < 1) {
2667
- height = 1;
2668
- }
2669
- p.tbody.style.height = height + 'px';
2670
- }
2671
- return this;
2672
- };
2673
-
2674
3897
  /**
2675
3898
  * Calculate the size required for the table body width (which is the row's width)
2676
3899
  * @private
2677
- * @returns {Number} calculated width
3900
+ * @returns {number} calculated width
2678
3901
  */
2679
3902
  DGTable.prototype._calculateTbodyWidth = function () {
2680
3903
  const p = this.p;
@@ -2736,7 +3959,7 @@ DGTable.prototype._calculateTbodyWidth = function () {
2736
3959
  * @public
2737
3960
  * @expose
2738
3961
  * @param {COLUMN_OPTIONS[]} columns - Column definitions array
2739
- * @param {Boolean=true} render - Should render now?
3962
+ * @param {boolean=true} render - Should render now?
2740
3963
  * @returns {DGTable} self
2741
3964
  */
2742
3965
  DGTable.prototype.setColumns = function (columns, render) {
@@ -2776,8 +3999,8 @@ DGTable.prototype.setColumns = function (columns, render) {
2776
3999
  * @public
2777
4000
  * @expose
2778
4001
  * @param {COLUMN_OPTIONS} columnData column properties
2779
- * @param {String|Number} [before=-1] column name or order to be inserted before
2780
- * @param {Boolean=true} render - Should render now?
4002
+ * @param {string|number} [before=-1] column name or order to be inserted before
4003
+ * @param {boolean=true} render - Should render now?
2781
4004
  * @returns {DGTable} self
2782
4005
  */
2783
4006
  DGTable.prototype.addColumn = function (columnData, before, render) {
@@ -2815,8 +4038,8 @@ DGTable.prototype.addColumn = function (columnData, before, render) {
2815
4038
  * Remove a column from the table
2816
4039
  * @public
2817
4040
  * @expose
2818
- * @param {String} column column name
2819
- * @param {Boolean=true} render - Should render now?
4041
+ * @param {string} column column name
4042
+ * @param {boolean=true} render - Should render now?
2820
4043
  * @returns {DGTable} self
2821
4044
  */
2822
4045
  DGTable.prototype.removeColumn = function (column, render) {
@@ -2840,7 +4063,7 @@ DGTable.prototype.removeColumn = function (column, render) {
2840
4063
  * Sets a new cell formatter.
2841
4064
  * @public
2842
4065
  * @expose
2843
- * @param {function(value: *, columnName: String, row: Object):String|null} [formatter=null] - The cell formatter. Should return an HTML.
4066
+ * @param {function(value: *, columnName: string, row: Object):string|null} [formatter=null] - The cell formatter. Should return an HTML.
2844
4067
  * @returns {DGTable} self
2845
4068
  */
2846
4069
  DGTable.prototype.setCellFormatter = function (formatter) {
@@ -2861,7 +4084,7 @@ DGTable.prototype.setCellFormatter = function (formatter) {
2861
4084
  * Sets a new header cell formatter.
2862
4085
  * @public
2863
4086
  * @expose
2864
- * @param {function(label: String, columnName: String):String|null} [formatter=null] - The cell formatter. Should return an HTML.
4087
+ * @param {function(label: string, columnName: string):string|null} [formatter=null] - The cell formatter. Should return an HTML.
2865
4088
  * @returns {DGTable} self
2866
4089
  */
2867
4090
  DGTable.prototype.setHeaderCellFormatter = function (formatter) {
@@ -2878,7 +4101,7 @@ DGTable.prototype.setHeaderCellFormatter = function (formatter) {
2878
4101
  /**
2879
4102
  * @public
2880
4103
  * @expose
2881
- * @param {function(row:Object,args:Object):Boolean|null} [filterFunc=null] - The filter function to work with filters. Default is a by-colum filter.
4104
+ * @param {function(row:Object,args:Object):boolean|null} [filterFunc=null] - The filter function to work with filters. Default is a by-colum filter.
2882
4105
  * @returns {DGTable} self
2883
4106
  */
2884
4107
  DGTable.prototype.setFilter = function (filterFunc) {
@@ -2970,8 +4193,8 @@ DGTable.prototype._refilter = function () {
2970
4193
  * Set a new label to a column
2971
4194
  * @public
2972
4195
  * @expose
2973
- * @param {String} column Name of the column
2974
- * @param {String} label New label for the column
4196
+ * @param {string} column Name of the column
4197
+ * @param {string} label New label for the column
2975
4198
  * @returns {DGTable} self
2976
4199
  */
2977
4200
  DGTable.prototype.setColumnLabel = function (column, label) {
@@ -3047,7 +4270,7 @@ DGTable.prototype.moveColumn = function (src, dest, visibleOnly = true) {
3047
4270
  let destWidth = p.visibleColumns[destOrder];
3048
4271
  destWidth = (destWidth.actualWidthConsideringScrollbarWidth || destWidth.actualWidth) + 'px';
3049
4272
 
3050
- let tbodyChildren = p.$tbody[0].childNodes;
4273
+ let tbodyChildren = p.tbody.childNodes;
3051
4274
  for (let i = 0, count = tbodyChildren.length; i < count; i++) {
3052
4275
  let row = tbodyChildren[i];
3053
4276
  if (row.nodeType !== 1) continue;
@@ -3067,9 +4290,9 @@ DGTable.prototype.moveColumn = function (src, dest, visibleOnly = true) {
3067
4290
  * Sort the table
3068
4291
  * @public
3069
4292
  * @expose
3070
- * @param {String?} column Name of the column to sort on (or null to remove sort arrow)
3071
- * @param {Boolean=} descending Sort in descending order
3072
- * @param {Boolean} [add=false] Should this sort be on top of the existing sort? (For multiple column sort)
4293
+ * @param {string?} column Name of the column to sort on (or null to remove sort arrow)
4294
+ * @param {boolean=} descending Sort in descending order
4295
+ * @param {boolean} [add=false] Should this sort be on top of the existing sort? (For multiple column sort)
3073
4296
  * @returns {DGTable} self
3074
4297
  */
3075
4298
  DGTable.prototype.sort = function (column, descending, add) {
@@ -3126,20 +4349,10 @@ DGTable.prototype.sort = function (column, descending, add) {
3126
4349
  this._showSortArrow(currentSort[i].column, currentSort[i].descending);
3127
4350
  }
3128
4351
 
3129
- if (o.adjustColumnWidthForSortArrow && !o._tableSkeletonNeedsRendering) {
4352
+ if (o.adjustColumnWidthForSortArrow && !p.tableSkeletonNeedsRendering) {
3130
4353
  this.tableWidthChanged(true);
3131
4354
  }
3132
4355
 
3133
- if (o.virtualTable) {
3134
- while (p.tbody && p.tbody.firstChild) {
3135
- this.trigger('rowdestroy', p.tbody.firstChild);
3136
- this._unbindCellEventsForRow(p.tbody.firstChild);
3137
- p.tbody.removeChild(p.tbody.firstChild);
3138
- }
3139
- } else {
3140
- p.tableSkeletonNeedsRendering = true;
3141
- }
3142
-
3143
4356
  p.rows.sortColumn = currentSort;
3144
4357
 
3145
4358
  let comparator;
@@ -3150,6 +4363,8 @@ DGTable.prototype.sort = function (column, descending, add) {
3150
4363
  }
3151
4364
  }
3152
4365
 
4366
+ p.virtualListHelper.invalidate().render();
4367
+
3153
4368
  // Build output for event, with option names that will survive compilers
3154
4369
  let sorts = [];
3155
4370
  for (let i = 0; i < currentSort.length; i++) {
@@ -3213,6 +4428,7 @@ DGTable.prototype._ensureVisibleColumns = function () {
3213
4428
  p.visibleColumns.push(p.columns[0]);
3214
4429
  this.trigger('showcolumn', p.columns[0].name);
3215
4430
  }
4431
+
3216
4432
  return this;
3217
4433
  };
3218
4434
 
@@ -3220,8 +4436,8 @@ DGTable.prototype._ensureVisibleColumns = function () {
3220
4436
  * Show or hide a column
3221
4437
  * @public
3222
4438
  * @expose
3223
- * @param {String} column Unique column name
3224
- * @param {Boolean} visible New visibility mode for the column
4439
+ * @param {string} column Unique column name
4440
+ * @param {boolean} visible New visibility mode for the column
3225
4441
  * @returns {DGTable} self
3226
4442
  */
3227
4443
  DGTable.prototype.setColumnVisible = function (column, visible) {
@@ -3246,7 +4462,7 @@ DGTable.prototype.setColumnVisible = function (column, visible) {
3246
4462
  * Get the visibility mode of a column
3247
4463
  * @public
3248
4464
  * @expose
3249
- * @returns {Boolean} true if visible
4465
+ * @returns {boolean} true if visible
3250
4466
  */
3251
4467
  DGTable.prototype.isColumnVisible = function (column) {
3252
4468
  const p = this.p;
@@ -3261,7 +4477,7 @@ DGTable.prototype.isColumnVisible = function (column) {
3261
4477
  * Globally set the minimum column width
3262
4478
  * @public
3263
4479
  * @expose
3264
- * @param {Number} minColumnWidth Minimum column width
4480
+ * @param {number} minColumnWidth Minimum column width
3265
4481
  * @returns {DGTable} self
3266
4482
  */
3267
4483
  DGTable.prototype.setMinColumnWidth = function (minColumnWidth) {
@@ -3278,7 +4494,7 @@ DGTable.prototype.setMinColumnWidth = function (minColumnWidth) {
3278
4494
  * Get the current minimum column width
3279
4495
  * @public
3280
4496
  * @expose
3281
- * @returns {Number} Minimum column width
4497
+ * @returns {number} Minimum column width
3282
4498
  */
3283
4499
  DGTable.prototype.getMinColumnWidth = function () {
3284
4500
  return this.o.minColumnWidth;
@@ -3288,7 +4504,7 @@ DGTable.prototype.getMinColumnWidth = function () {
3288
4504
  * Set the limit on concurrent columns sorted
3289
4505
  * @public
3290
4506
  * @expose
3291
- * @param {Number} sortableColumns How many sortable columns to allow?
4507
+ * @param {number} sortableColumns How many sortable columns to allow?
3292
4508
  * @returns {DGTable} self
3293
4509
  */
3294
4510
  DGTable.prototype.setSortableColumns = function (sortableColumns) {
@@ -3309,7 +4525,7 @@ DGTable.prototype.setSortableColumns = function (sortableColumns) {
3309
4525
  * Get the limit on concurrent columns sorted
3310
4526
  * @public
3311
4527
  * @expose
3312
- * @returns {Number} How many sortable columns are allowed?
4528
+ * @returns {number} How many sortable columns are allowed?
3313
4529
  */
3314
4530
  DGTable.prototype.getSortableColumns = function () {
3315
4531
  return this.o.sortableColumns;
@@ -3318,7 +4534,7 @@ DGTable.prototype.getSortableColumns = function () {
3318
4534
  /**
3319
4535
  * @public
3320
4536
  * @expose
3321
- * @param {Boolean?} movableColumns=true are the columns movable?
4537
+ * @param {boolean?} movableColumns=true are the columns movable?
3322
4538
  * @returns {DGTable} self
3323
4539
  */
3324
4540
  DGTable.prototype.setMovableColumns = function (movableColumns) {
@@ -3334,7 +4550,7 @@ DGTable.prototype.setMovableColumns = function (movableColumns) {
3334
4550
  /**
3335
4551
  * @public
3336
4552
  * @expose
3337
- * @returns {Boolean} are the columns movable?
4553
+ * @returns {boolean} are the columns movable?
3338
4554
  */
3339
4555
  DGTable.prototype.getMovableColumns = function () {
3340
4556
  return this.o.movableColumns;
@@ -3343,7 +4559,7 @@ DGTable.prototype.getMovableColumns = function () {
3343
4559
  /**
3344
4560
  * @public
3345
4561
  * @expose
3346
- * @param {Boolean} resizableColumns=true are the columns resizable?
4562
+ * @param {boolean} resizableColumns=true are the columns resizable?
3347
4563
  * @returns {DGTable} self
3348
4564
  */
3349
4565
  DGTable.prototype.setResizableColumns = function (resizableColumns) {
@@ -3359,7 +4575,7 @@ DGTable.prototype.setResizableColumns = function (resizableColumns) {
3359
4575
  /**
3360
4576
  * @public
3361
4577
  * @expose
3362
- * @returns {Boolean} are the columns resizable?
4578
+ * @returns {boolean} are the columns resizable?
3363
4579
  */
3364
4580
  DGTable.prototype.getResizableColumns = function () {
3365
4581
  return this.o.resizableColumns;
@@ -3383,8 +4599,8 @@ DGTable.prototype.setComparatorCallback = function (comparatorCallback) {
3383
4599
  * Set a new width to a column
3384
4600
  * @public
3385
4601
  * @expose
3386
- * @param {String} column name of the column to resize
3387
- * @param {Number|String} width new column as pixels, or relative size (0.5, 50%)
4602
+ * @param {string} column name of the column to resize
4603
+ * @param {number|string} width new column as pixels, or relative size (0.5, 50%)
3388
4604
  * @returns {DGTable} self
3389
4605
  */
3390
4606
  DGTable.prototype.setColumnWidth = function (column, width) {
@@ -3415,8 +4631,8 @@ DGTable.prototype.setColumnWidth = function (column, width) {
3415
4631
  /**
3416
4632
  * @public
3417
4633
  * @expose
3418
- * @param {String} column name of the column
3419
- * @returns {String|null} the serialized width of the specified column, or null if column not found
4634
+ * @param {string} column name of the column
4635
+ * @returns {string|null} the serialized width of the specified column, or null if column not found
3420
4636
  */
3421
4637
  DGTable.prototype.getColumnWidth = function (column) {
3422
4638
  const p = this.p;
@@ -3431,7 +4647,7 @@ DGTable.prototype.getColumnWidth = function (column) {
3431
4647
  /**
3432
4648
  * @public
3433
4649
  * @expose
3434
- * @param {String} column name of the column
4650
+ * @param {string} column name of the column
3435
4651
  * @returns {SERIALIZED_COLUMN|null} configuration for all columns
3436
4652
  */
3437
4653
  DGTable.prototype.getColumnConfig = function (column) {
@@ -3559,25 +4775,20 @@ DGTable.prototype._getHtmlForCell = function (rowData, column) {
3559
4775
  * Returns the y pos of a row by index
3560
4776
  * @public
3561
4777
  * @expose
3562
- * @param {Number} rowIndex - index of the row
3563
- * @returns {Number|null} Y pos
4778
+ * @param {number} rowIndex - index of the row
4779
+ * @returns {number|null} Y pos
3564
4780
  */
3565
4781
  DGTable.prototype.getRowYPos = function (rowIndex) {
3566
4782
  const p = this.p;
3567
4783
 
3568
- if (this.o.virtualTable) {
3569
- return rowIndex > 0 ? p.virtualRowHeightFirst + (rowIndex - 1) * p.virtualRowHeight : 0;
3570
- } else {
3571
- let row = p.tbody.childNodes[rowIndex];
3572
- return row ? row.offsetTop : null;
3573
- }
4784
+ return p.virtualListHelper.getItemPosition(rowIndex) || null;
3574
4785
  };
3575
4786
 
3576
4787
  /**
3577
4788
  * Returns the row data for a specific row
3578
4789
  * @public
3579
4790
  * @expose
3580
- * @param {Number} row index of the row
4791
+ * @param {number} row index of the row
3581
4792
  * @returns {Object} Row data
3582
4793
  */
3583
4794
  DGTable.prototype.getDataForRow = function (row) {
@@ -3591,7 +4802,7 @@ DGTable.prototype.getDataForRow = function (row) {
3591
4802
  * Gets the number of rows
3592
4803
  * @public
3593
4804
  * @expose
3594
- * @returns {Number} Row count
4805
+ * @returns {number} Row count
3595
4806
  */
3596
4807
  DGTable.prototype.getRowCount = function () {
3597
4808
  const p = this.p;
@@ -3603,7 +4814,7 @@ DGTable.prototype.getRowCount = function () {
3603
4814
  * @public
3604
4815
  * @expose
3605
4816
  * @param {Object} rowData - Row data to find
3606
- * @returns {Number} Row index
4817
+ * @returns {number} Row index
3607
4818
  */
3608
4819
  DGTable.prototype.getIndexForRow = function (rowData) {
3609
4820
  const p = this.p;
@@ -3614,7 +4825,7 @@ DGTable.prototype.getIndexForRow = function (rowData) {
3614
4825
  * Gets the number of filtered rows
3615
4826
  * @public
3616
4827
  * @expose
3617
- * @returns {Number} Filtered row count
4828
+ * @returns {number} Filtered row count
3618
4829
  */
3619
4830
  DGTable.prototype.getFilteredRowCount = function () {
3620
4831
  const p = this.p;
@@ -3626,7 +4837,7 @@ DGTable.prototype.getFilteredRowCount = function () {
3626
4837
  * @public
3627
4838
  * @expose
3628
4839
  * @param {Object} rowData - Row data to find
3629
- * @returns {Number} Row index
4840
+ * @returns {number} Row index
3630
4841
  */
3631
4842
  DGTable.prototype.getIndexForFilteredRow = function (rowData) {
3632
4843
  const p = this.p;
@@ -3637,7 +4848,7 @@ DGTable.prototype.getIndexForFilteredRow = function (rowData) {
3637
4848
  * Returns the row data for a specific row
3638
4849
  * @public
3639
4850
  * @expose
3640
- * @param {Number} row index of the filtered row
4851
+ * @param {number} row index of the filtered row
3641
4852
  * @returns {Object} Row data
3642
4853
  */
3643
4854
  DGTable.prototype.getDataForFilteredRow = function (row) {
@@ -3659,7 +4870,7 @@ DGTable.prototype.getHeaderRowElement = function () {
3659
4870
  /**
3660
4871
  * @private
3661
4872
  * @param {Element} el
3662
- * @returns {Number} width
4873
+ * @returns {number} width
3663
4874
  */
3664
4875
  DGTable.prototype._horizontalPadding = function (el) {
3665
4876
  return (parseFloat($.css(el, 'padding-left')) || 0) + (
@@ -3669,7 +4880,7 @@ DGTable.prototype._horizontalPadding = function (el) {
3669
4880
  /**
3670
4881
  * @private
3671
4882
  * @param {Element} el
3672
- * @returns {Number} width
4883
+ * @returns {number} width
3673
4884
  */
3674
4885
  DGTable.prototype._horizontalBorderWidth = function (el) {
3675
4886
  return (parseFloat($.css(el, 'border-left')) || 0) + (
@@ -3678,28 +4889,28 @@ DGTable.prototype._horizontalBorderWidth = function (el) {
3678
4889
 
3679
4890
  /**
3680
4891
  * @private
3681
- * @returns {Number} width
4892
+ * @returns {number} width
3682
4893
  */
3683
4894
  DGTable.prototype._calculateWidthAvailableForColumns = function () {
3684
4895
  const o = this.o,p = this.p;
3685
4896
 
3686
4897
  // Changing display mode briefly, to prevent taking in account the parent's scrollbar width when we are the cause for it
3687
4898
  let oldDisplay, lastScrollTop, lastScrollLeft;
3688
- if (p.$table) {
4899
+ if (p.table) {
3689
4900
  lastScrollTop = p.table ? p.table.scrollTop : 0;
3690
4901
  lastScrollLeft = p.table ? p.table.scrollLeft : 0;
3691
4902
 
3692
4903
  if (o.virtualTable) {
3693
- oldDisplay = p.$table[0].style.display;
3694
- p.$table[0].style.display = 'none';
4904
+ oldDisplay = p.table.style.display;
4905
+ p.table.style.display = 'none';
3695
4906
  }
3696
4907
  }
3697
4908
 
3698
4909
  let detectedWidth = Css.getElementWidth(this.$el[0]);
3699
4910
 
3700
- if (p.$table) {
4911
+ if (p.table) {
3701
4912
  if (o.virtualTable) {
3702
- p.$table[0].style.display = oldDisplay;
4913
+ p.table.style.display = oldDisplay;
3703
4914
  }
3704
4915
 
3705
4916
  p.table.scrollTop = lastScrollTop;
@@ -3773,8 +4984,8 @@ DGTable.prototype.tableWidthChanged = function () {
3773
4984
  /**
3774
4985
  * @public
3775
4986
  * @expose
3776
- * @param {Boolean} [forceUpdate=false]
3777
- * @param {Boolean} [renderColumns=true]
4987
+ * @param {boolean} [forceUpdate=false]
4988
+ * @param {boolean} [renderColumns=true]
3778
4989
  * @returns {DGTable} self
3779
4990
  */
3780
4991
  return function (forceUpdate, renderColumns) {
@@ -3800,7 +5011,7 @@ DGTable.prototype.tableWidthChanged = function () {
3800
5011
  tableWidthBeforeCalculations = parseFloat(p.tbody.style.minWidth) || 0;
3801
5012
  }
3802
5013
 
3803
- if (sizeLeft !== lastDetectedWidth || forceUpdate) {
5014
+ if (sizeLeft !== lastDetectedWidth || forceUpdate) {var _p$notifyRendererOfCo2;
3804
5015
  lastDetectedWidth = detectedWidth;
3805
5016
 
3806
5017
  let absWidthTotal = 0,changedColumnIndexes = [],totalRelativePercentage = 0;
@@ -3975,6 +5186,8 @@ DGTable.prototype.tableWidthChanged = function () {
3975
5186
  p.visibleColumns[p.visibleColumns.length - 1].actualWidth - (p.scrollbarWidth || 0);
3976
5187
  }
3977
5188
 
5189
+ (_p$notifyRendererOfCo2 = p.notifyRendererOfColumnsConfig) === null || _p$notifyRendererOfCo2 === void 0 ? void 0 : _p$notifyRendererOfCo2.call(p);
5190
+
3978
5191
  if (renderColumns) {
3979
5192
  let tableWidth = this._calculateTbodyWidth();
3980
5193
 
@@ -4037,9 +5250,9 @@ DGTable.prototype.tableHeightChanged = function () {
4037
5250
  * @public
4038
5251
  * @expose
4039
5252
  * @param {Object[]} data - array of rows to add to the table
4040
- * @param {Number} [at=-1] - where to add the rows at
4041
- * @param {Boolean} [resort=false] - should resort all rows?
4042
- * @param {Boolean} [render=true]
5253
+ * @param {number} [at=-1] - where to add the rows at
5254
+ * @param {boolean} [resort=false] - should resort all rows?
5255
+ * @param {boolean} [render=true]
4043
5256
  * @returns {DGTable} self
4044
5257
  */
4045
5258
  DGTable.prototype.addRows = function (data, at, resort, render) {
@@ -4079,39 +5292,18 @@ DGTable.prototype.addRows = function (data, at, resort, render) {
4079
5292
  }
4080
5293
 
4081
5294
  } else if (render) {
4082
- let childNodes = p.tbody.childNodes;
5295
+ p.virtualListHelper.addItemsAt(data.length, at);
4083
5296
 
4084
5297
  if (that.o.virtualTable) {
4085
-
4086
- while (p.tbody.firstChild) {
4087
- this.trigger('rowdestroy', p.tbody.firstChild);
4088
- this._unbindCellEventsForRow(p.tbody.firstChild);
4089
- p.tbody.removeChild(p.tbody.firstChild);
4090
- }
4091
-
4092
- this._calculateVirtualHeight() // Calculate virtual height
4093
- ._updateLastCellWidthFromScrollbar() // Detect vertical scrollbar height
5298
+ this._updateVirtualHeight().
5299
+ _updateLastCellWidthFromScrollbar() // Detect vertical scrollbar height
4094
5300
  .render().
4095
5301
  _updateTableWidth(false); // Update table width to suit the required width considering vertical scrollbar
4096
5302
 
4097
- } else if (p.$tbody) {
4098
-
4099
- let firstRow = at,
4100
- lastRow = at + data.length - 1;
4101
-
4102
- let renderedRows = that.renderRows(firstRow, lastRow);
4103
- p.tbody.insertBefore(renderedRows, childNodes[at] || null);
4104
-
4105
- for (let i = lastRow + 1; i < childNodes.length; i++) {
4106
- let row = childNodes[i];
4107
- row['rowIndex'] += data.length;
4108
- row['physicalRowIndex'] += data.length;
4109
- }
4110
-
5303
+ } else if (p.tbody) {
4111
5304
  this.render().
4112
5305
  _updateLastCellWidthFromScrollbar() // Detect vertical scrollbar height, and update existing last cells
4113
5306
  ._updateTableWidth(true); // Update table width to suit the required width considering vertical scrollbar
4114
-
4115
5307
  }
4116
5308
  }
4117
5309
 
@@ -4124,9 +5316,9 @@ DGTable.prototype.addRows = function (data, at, resort, render) {
4124
5316
  * Removes a row from the table
4125
5317
  * @public
4126
5318
  * @expose
4127
- * @param {Number} physicalRowIndex - index
4128
- * @param {Number} count - how many rows to remove
4129
- * @param {Boolean=true} render
5319
+ * @param {number} physicalRowIndex - index
5320
+ * @param {number} count - how many rows to remove
5321
+ * @param {boolean=true} render
4130
5322
  * @returns {DGTable} self
4131
5323
  */
4132
5324
  DGTable.prototype.removeRows = function (physicalRowIndex, count, render) {
@@ -4152,49 +5344,19 @@ DGTable.prototype.removeRows = function (physicalRowIndex, count, render) {
4152
5344
  }
4153
5345
 
4154
5346
  } else if (render) {
4155
-
4156
- let childNodes = p.tbody.childNodes;
5347
+ p.virtualListHelper.removeItemsAt(count, physicalRowIndex);
4157
5348
 
4158
5349
  if (this.o.virtualTable) {
4159
-
4160
- while (p.tbody.firstChild) {
4161
- this.trigger('rowdestroy', p.tbody.firstChild);
4162
- this._unbindCellEventsForRow(p.tbody.firstChild);
4163
- p.tbody.removeChild(p.tbody.firstChild);
4164
- }
4165
-
4166
- this._calculateVirtualHeight().
5350
+ this._updateVirtualHeight().
4167
5351
  _updateLastCellWidthFromScrollbar().
4168
5352
  render().
4169
5353
  _updateTableWidth(false); // Update table width to suit the required width considering vertical scrollbar
4170
5354
 
4171
5355
 
4172
5356
  } else {
4173
-
4174
- let lastRowIndex = physicalRowIndex + count - 1;
4175
-
4176
- for (let i = 0; i < childNodes.length; i++) {
4177
- let row = childNodes[i];
4178
- let index = row['physicalRowIndex'];
4179
-
4180
- if (index >= physicalRowIndex) {
4181
- if (index <= lastRowIndex) {
4182
- this.trigger('rowdestroy', row);
4183
- this._unbindCellEventsForRow(row);
4184
- p.tbody.removeChild(row);
4185
- i--;
4186
- } else {
4187
- row['physicalRowIndex'] -= count;
4188
- }
4189
- } else {
4190
- row['rowIndex'] = i;
4191
- }
4192
- }
4193
-
4194
5357
  this.render().
4195
5358
  _updateLastCellWidthFromScrollbar().
4196
5359
  _updateTableWidth(true); // Update table width to suit the required width considering vertical scrollbar
4197
-
4198
5360
  }
4199
5361
  }
4200
5362
 
@@ -4205,8 +5367,8 @@ DGTable.prototype.removeRows = function (physicalRowIndex, count, render) {
4205
5367
  * Removes a row from the table
4206
5368
  * @public
4207
5369
  * @expose
4208
- * @param {Number} physicalRowIndex - index
4209
- * @param {Boolean=true} render
5370
+ * @param {number} physicalRowIndex - index
5371
+ * @param {boolean=true} render
4210
5372
  * @returns {DGTable} self
4211
5373
  */
4212
5374
  DGTable.prototype.removeRow = function (physicalRowIndex, render) {
@@ -4217,7 +5379,7 @@ DGTable.prototype.removeRow = function (physicalRowIndex, render) {
4217
5379
  * Refreshes the row specified
4218
5380
  * @public
4219
5381
  * @expose
4220
- * @param {Number} physicalRowIndex index
5382
+ * @param {number} physicalRowIndex index
4221
5383
  * @returns {DGTable} self
4222
5384
  */
4223
5385
  DGTable.prototype.refreshRow = function (physicalRowIndex) {
@@ -4234,34 +5396,7 @@ DGTable.prototype.refreshRow = function (physicalRowIndex) {
4234
5396
  rowIndex = physicalRowIndex;
4235
5397
  }
4236
5398
 
4237
- let childNodes = p.tbody.childNodes;
4238
-
4239
- if (this.o.virtualTable) {
4240
- // Now make sure that the row actually rendered, as this is a virtual table
4241
- let isRowVisible = false;
4242
- let i = 0;
4243
-
4244
- for (; i < childNodes.length; i++) {
4245
- if (childNodes[i]['physicalRowIndex'] === physicalRowIndex) {
4246
- isRowVisible = true;
4247
- this.trigger('rowdestroy', childNodes[i]);
4248
- this._unbindCellEventsForRow(childNodes[i]);
4249
- p.tbody.removeChild(childNodes[i]);
4250
- break;
4251
- }
4252
- }
4253
-
4254
- if (isRowVisible) {
4255
- let renderedRow = this.renderRows(rowIndex, rowIndex);
4256
- p.tbody.insertBefore(renderedRow, childNodes[i] || null);
4257
- }
4258
- } else {
4259
- this.trigger('rowdestroy', childNodes[rowIndex]);
4260
- this._unbindCellEventsForRow(childNodes[rowIndex]);
4261
- p.tbody.removeChild(childNodes[rowIndex]);
4262
- let renderedRow = this.renderRows(rowIndex, rowIndex);
4263
- p.tbody.insertBefore(renderedRow, childNodes[rowIndex] || null);
4264
- }
5399
+ p.virtualListHelper.refreshItemAt(rowIndex);
4265
5400
 
4266
5401
  return this;
4267
5402
  };
@@ -4270,7 +5405,7 @@ DGTable.prototype.refreshRow = function (physicalRowIndex) {
4270
5405
  * Get the DOM element for the specified row, if it exists
4271
5406
  * @public
4272
5407
  * @expose
4273
- * @param {Number} physicalRowIndex index
5408
+ * @param {number} physicalRowIndex index
4274
5409
  * @returns {Element|null} row or null
4275
5410
  */
4276
5411
  DGTable.prototype.getRowElement = function (physicalRowIndex) {
@@ -4287,20 +5422,7 @@ DGTable.prototype.getRowElement = function (physicalRowIndex) {
4287
5422
  rowIndex = physicalRowIndex;
4288
5423
  }
4289
5424
 
4290
- let childNodes = p.tbody.childNodes;
4291
-
4292
- if (this.o.virtualTable) {
4293
- // Now make sure that the row actually rendered, as this is a virtual table
4294
- for (let i = 0; i < childNodes.length; i++) {
4295
- if (childNodes[i]['physicalRowIndex'] === physicalRowIndex) {
4296
- return childNodes[i];
4297
- }
4298
- }
4299
- } else {
4300
- return childNodes[rowIndex];
4301
- }
4302
-
4303
- return null;
5425
+ return p.virtualListHelper.getItemElementAt(rowIndex) || null;
4304
5426
  };
4305
5427
 
4306
5428
  /**
@@ -4310,29 +5432,8 @@ DGTable.prototype.getRowElement = function (physicalRowIndex) {
4310
5432
  * @returns {DGTable} self
4311
5433
  */
4312
5434
  DGTable.prototype.refreshAllVirtualRows = function () {
4313
-
4314
5435
  const p = this.p;
4315
-
4316
- if (this.o.virtualTable) {
4317
- // Now make sure that the row actually rendered, as this is a virtual table
4318
- let rowsToRender = [];
4319
- let childNodes = p.tbody.childNodes;
4320
-
4321
- for (let i = 0, rowCount = childNodes.length; i < rowCount; i++) {
4322
- rowsToRender.push(childNodes[i]['physicalRowIndex']);
4323
- this.trigger('rowdestroy', childNodes[i]);
4324
- this._unbindCellEventsForRow(childNodes[i]);
4325
- p.tbody.removeChild(childNodes[i]);
4326
- i--;
4327
- rowCount--;
4328
- }
4329
-
4330
- for (let i = 0; i < rowsToRender.length; i++) {
4331
- let renderedRow = this.renderRows(rowsToRender[i], rowsToRender[i]);
4332
- p.tbody.appendChild(renderedRow);
4333
- }
4334
- }
4335
-
5436
+ p.virtualListHelper.invalidate().render();
4336
5437
  return this;
4337
5438
  };
4338
5439
 
@@ -4341,7 +5442,7 @@ DGTable.prototype.refreshAllVirtualRows = function () {
4341
5442
  * @public
4342
5443
  * @expose
4343
5444
  * @param {Object[]} data array of rows to add to the table
4344
- * @param {Boolean} [resort=false] should resort all rows?
5445
+ * @param {boolean} [resort=false] should resort all rows?
4345
5446
  * @returns {DGTable} self
4346
5447
  */
4347
5448
  DGTable.prototype.setRows = function (data, resort) {
@@ -4369,7 +5470,7 @@ DGTable.prototype.setRows = function (data, resort) {
4369
5470
  * @public
4370
5471
  * @expose
4371
5472
  * @param {string} id Id of the element containing your data
4372
- * @returns {String|null} the url, or null if not supported
5473
+ * @returns {string|null} the url, or null if not supported
4373
5474
  */
4374
5475
  DGTable.prototype.getUrlForElementContent = function (id) {
4375
5476
  let blob,
@@ -4395,7 +5496,7 @@ DGTable.prototype.getUrlForElementContent = function (id) {
4395
5496
  /**
4396
5497
  * @public
4397
5498
  * @expose
4398
- * @returns {Boolean} A value indicating whether Web Workers are supported
5499
+ * @returns {boolean} A value indicating whether Web Workers are supported
4399
5500
  */
4400
5501
  DGTable.prototype.isWorkerSupported = function () {
4401
5502
  return window['Worker'] instanceof Function;
@@ -4490,10 +5591,6 @@ DGTable.prototype.cancelColumnResize = function () {
4490
5591
  return this;
4491
5592
  };
4492
5593
 
4493
- DGTable.prototype._onVirtualTableScrolled = function () {
4494
- this.render();
4495
- };
4496
-
4497
5594
  DGTable.prototype._onTableScrolledHorizontally = function () {
4498
5595
  const p = this.p;
4499
5596
 
@@ -4504,7 +5601,7 @@ DGTable.prototype._onTableScrolledHorizontally = function () {
4504
5601
  * Reverse-calculate the column to resize from mouse position
4505
5602
  * @private
4506
5603
  * @param {jQuery_Event} e jQuery mouse event
4507
- * @returns {String} name of the column which the mouse is over, or null if the mouse is not in resize position
5604
+ * @returns {string} name of the column which the mouse is over, or null if the mouse is not in resize position
4508
5605
  */
4509
5606
  DGTable.prototype._getColumnByResizePosition = function (e) {
4510
5607
 
@@ -5085,12 +6182,12 @@ DGTable.prototype._clearSortArrows = function () {
5085
6182
  let tableClassName = this.o.tableClassName;
5086
6183
  let sortedColumns = p.$headerRow.find('>div.' + tableClassName + '-header-cell.sorted');
5087
6184
  let arrows = sortedColumns.find('>div>.sort-arrow');
5088
- for (let arrow of arrows) {
6185
+ arrows.each((_, arrow) => {
5089
6186
  let col = p.columns.get(arrow.parentNode.parentNode['columnName']);
5090
6187
  if (col) {
5091
6188
  col.arrowProposedWidth = 0;
5092
6189
  }
5093
- }
6190
+ });
5094
6191
  arrows.remove();
5095
6192
  sortedColumns.removeClass('sorted').removeClass('desc');
5096
6193
  }
@@ -5099,8 +6196,8 @@ DGTable.prototype._clearSortArrows = function () {
5099
6196
 
5100
6197
  /**
5101
6198
  * @private
5102
- * @param {String} column the name of the sort column
5103
- * @param {Boolean} descending table is sorted descending
6199
+ * @param {string} column the name of the sort column
6200
+ * @param {boolean} descending table is sorted descending
5104
6201
  * @returns {DGTable} self
5105
6202
  */
5106
6203
  DGTable.prototype._showSortArrow = function (column, descending) {
@@ -5128,7 +6225,7 @@ DGTable.prototype._showSortArrow = function (column, descending) {
5128
6225
 
5129
6226
  /**
5130
6227
  * @private
5131
- * @param {Number} cellIndex index of the column in the DOM
6228
+ * @param {number} cellIndex index of the column in the DOM
5132
6229
  * @returns {DGTable} self
5133
6230
  */
5134
6231
  DGTable.prototype._resizeColumnElements = function (cellIndex) {
@@ -5143,11 +6240,11 @@ DGTable.prototype._resizeColumnElements = function (cellIndex) {
5143
6240
  headerCells[cellIndex].style.width = (col.actualWidthConsideringScrollbarWidth || col.actualWidth) + 'px';
5144
6241
 
5145
6242
  let width = (col.actualWidthConsideringScrollbarWidth || col.actualWidth) + 'px';
5146
- let tbodyChildren = p.$tbody[0].childNodes;
6243
+ let tbodyChildren = p.tbody.childNodes;
5147
6244
  for (let i = 0, count = tbodyChildren.length; i < count; i++) {
5148
- let headerRow = tbodyChildren[i];
5149
- if (headerRow.nodeType !== 1) continue;
5150
- headerRow.childNodes[cellIndex].style.width = width;
6245
+ let rowEl = tbodyChildren[i];
6246
+ if (rowEl.nodeType !== 1) continue;
6247
+ rowEl.childNodes[cellIndex].style.width = width;
5151
6248
  }
5152
6249
  }
5153
6250
 
@@ -5176,22 +6273,18 @@ DGTable.prototype._destroyHeaderCells = function () {
5176
6273
  * @private
5177
6274
  * @returns {DGTable} self
5178
6275
  */
5179
- DGTable.prototype._renderSkeletonBase = function () {
6276
+ DGTable.prototype._renderSkeletonBase = function () {var _p$virtualListHelper2;
5180
6277
  let that = this,
5181
6278
  p = that.p,
5182
6279
  o = that.o;
5183
6280
 
5184
6281
  // Clean up old elements
5185
6282
 
6283
+ (_p$virtualListHelper2 = p.virtualListHelper) === null || _p$virtualListHelper2 === void 0 ? void 0 : _p$virtualListHelper2.destroy();
6284
+ p.virtualListHelper = null;
6285
+
5186
6286
  if (p.$table && o.virtualTable) {
5187
6287
  p.$table.remove();
5188
- if (p.$tbody) {
5189
- let rows = p.$tbody[0].childNodes;
5190
- for (let i = 0, len = rows.length; i < len; i++) {
5191
- that.trigger('rowdestroy', rows[i]);
5192
- that._unbindCellEventsForRow(rows[i]);
5193
- }
5194
- }
5195
6288
  p.$table = p.table = p.$tbody = p.tbody = null;
5196
6289
  }
5197
6290
 
@@ -5324,44 +6417,6 @@ DGTable.prototype._renderSkeletonBody = function () {
5324
6417
 
5325
6418
  let tableClassName = o.tableClassName;
5326
6419
 
5327
- // Calculate virtual row heights
5328
- if (o.virtualTable && !p.virtualRowHeight) {
5329
- let createDummyRow = function () {
5330
- let row = createElement('div'),
5331
- cell = row.appendChild(createElement('div')),
5332
- cellInner = cell.appendChild(createElement('div'));
5333
- row.className = tableClassName + '-row';
5334
- cell.className = tableClassName + '-cell';
5335
- cellInner.innerHTML = '0';
5336
- row.style.visibility = 'hidden';
5337
- row.style.position = 'absolute';
5338
- return row;
5339
- };
5340
-
5341
- let $dummyTbody,$dummyWrapper = $('<div>').
5342
- addClass(that.el.className).
5343
- css({ 'z-index': -1, 'position': 'absolute', left: '0', top: '-9999px', width: '1px', overflow: 'hidden' }).
5344
- append(
5345
- $('<div>').addClass(tableClassName).append(
5346
- $dummyTbody = $('<div>').addClass(tableClassName + '-body').css('width', 99999)));
5347
-
5348
-
5349
-
5350
- $dummyWrapper.appendTo(document.body);
5351
-
5352
- let row1 = createDummyRow(),row2 = createDummyRow(),row3 = createDummyRow();
5353
- $dummyTbody.append(row1, row2, row3);
5354
-
5355
- p.virtualRowHeightFirst = Css.getElementHeight(row1, true, true, true);
5356
- p.virtualRowHeight = Css.getElementHeight(row2, true, true, true);
5357
- p.virtualRowHeightLast = Css.getElementHeight(row3, true, true, true);
5358
-
5359
- p.virtualRowHeightMin = Math.min(Math.min(p.virtualRowHeightFirst, p.virtualRowHeight), p.virtualRowHeightLast);
5360
- p.virtualRowHeightMax = Math.max(Math.max(p.virtualRowHeightFirst, p.virtualRowHeight), p.virtualRowHeightLast);
5361
-
5362
- $dummyWrapper.remove();
5363
- }
5364
-
5365
6420
  // Create inner table and tbody
5366
6421
  if (!p.$table) {
5367
6422
 
@@ -5394,22 +6449,19 @@ DGTable.prototype._renderSkeletonBody = function () {
5394
6449
  let tbody = createElement('div');
5395
6450
  let $tbody = $(tbody);
5396
6451
  tbody.className = o.tableClassName + '-body';
6452
+ tbody.style.minHeight = '1px';
5397
6453
  p.table = table;
5398
6454
  p.tbody = tbody;
5399
6455
  p.$table = $table;
5400
6456
  p.$tbody = $tbody;
5401
6457
 
5402
- if (o.virtualTable) {
5403
- p.virtualVisibleRows = Math.ceil(p.visibleHeight / p.virtualRowHeightMin);
5404
- }
5405
-
5406
- that._calculateVirtualHeight();
5407
-
5408
6458
  relativizeElement($tbody);
5409
6459
  relativizeElement($table);
5410
6460
 
5411
6461
  table.appendChild(tbody);
5412
6462
  that.el.appendChild(fragment);
6463
+
6464
+ this._setupVirtualTable();
5413
6465
  }
5414
6466
 
5415
6467
  return this;
@@ -5424,6 +6476,25 @@ DGTable.prototype._renderSkeleton = function () {
5424
6476
  return this;
5425
6477
  };
5426
6478
 
6479
+ /**
6480
+ * @private
6481
+ * @returns {DGTable} self
6482
+ */
6483
+ DGTable.prototype._updateVirtualHeight = function () {
6484
+ const o = this.o,p = this.p;
6485
+
6486
+ if (!p.tbody)
6487
+ return this;
6488
+
6489
+ if (o.virtualTable) {
6490
+ p.tbody.style.height = p.virtualListHelper.estimateFullHeight() + 'px';
6491
+ } else {
6492
+ p.tbody.style.height = '';
6493
+ }
6494
+
6495
+ return this;
6496
+ };
6497
+
5427
6498
  /**
5428
6499
  * @private
5429
6500
  * @returns {DGTable} self
@@ -5434,7 +6505,7 @@ DGTable.prototype._updateLastCellWidthFromScrollbar = function (force) {
5434
6505
 
5435
6506
  // Calculate scrollbar's width and reduce from lat column's width
5436
6507
  let scrollbarWidth = p.table.offsetWidth - p.table.clientWidth;
5437
- if (scrollbarWidth !== p.scrollbarWidth || force) {
6508
+ if (scrollbarWidth !== p.scrollbarWidth || force) {var _p$notifyRendererOfCo3;
5438
6509
  p.scrollbarWidth = scrollbarWidth;
5439
6510
  for (let i = 0; i < p.columns.length; i++) {
5440
6511
  p.columns[i].actualWidthConsideringScrollbarWidth = null;
@@ -5455,7 +6526,10 @@ DGTable.prototype._updateLastCellWidthFromScrollbar = function (force) {
5455
6526
 
5456
6527
  p.headerRow.childNodes[lastColIndex].style.width = lastColWidth;
5457
6528
  }
6529
+
6530
+ (_p$notifyRendererOfCo3 = p.notifyRendererOfColumnsConfig) === null || _p$notifyRendererOfCo3 === void 0 ? void 0 : _p$notifyRendererOfCo3.call(p);
5458
6531
  }
6532
+
5459
6533
  return this;
5460
6534
  };
5461
6535
 
@@ -5477,7 +6551,7 @@ DGTable.prototype._updateTableWidth = function (parentSizeMayHaveChanged) {
5477
6551
  if (o.width === DGTable.Width.AUTO) {
5478
6552
  // Update wrapper element's size to fully contain the table body
5479
6553
 
5480
- Css.setElementWidth(p.$table[0], Css.getElementWidth(p.$tbody[0], true, true, true));
6554
+ Css.setElementWidth(p.$table[0], Css.getElementWidth(p.tbody, true, true, true));
5481
6555
  Css.setElementWidth(this.$el[0], Css.getElementWidth(p.$table[0], true, true, true));
5482
6556
 
5483
6557
  } else if (o.width === DGTable.Width.SCROLL) {
@@ -5502,7 +6576,7 @@ DGTable.prototype._updateTableWidth = function (parentSizeMayHaveChanged) {
5502
6576
 
5503
6577
  /**
5504
6578
  * @private
5505
- * @returns {Boolean}
6579
+ * @returns {boolean}
5506
6580
  */
5507
6581
  DGTable.prototype._isTableRtl = function () {
5508
6582
  return this.p.$table.css('direction') === 'rtl';
@@ -5511,7 +6585,7 @@ DGTable.prototype._isTableRtl = function () {
5511
6585
  /**
5512
6586
  * @private
5513
6587
  * @param {Object} column column object
5514
- * @returns {String}
6588
+ * @returns {string}
5515
6589
  */
5516
6590
  DGTable.prototype._serializeColumnWidth = function (column) {
5517
6591
  return column.widthMode === ColumnWidthMode.AUTO ? 'auto' :
@@ -5797,15 +6871,15 @@ DGTable.prototype.hideCellPreview = function () {
5797
6871
 
5798
6872
  /**
5799
6873
  * @typedef {Object} SERIALIZED_COLUMN
5800
- * @property {Number|null|undefined} [order=0]
5801
- * @property {String|null|undefined} [width='auto']
5802
- * @property {Boolean|null|undefined} [visible=true]
6874
+ * @property {number|null|undefined} [order=0]
6875
+ * @property {string|null|undefined} [width='auto']
6876
+ * @property {boolean|null|undefined} [visible=true]
5803
6877
  * */
5804
6878
 
5805
6879
  /**
5806
6880
  * @typedef {Object} SERIALIZED_COLUMN_SORT
5807
- * @property {String|null|undefined} [column='']
5808
- * @property {Boolean|null|undefined} [descending=false]
6881
+ * @property {string|null|undefined} [column='']
6882
+ * @property {boolean|null|undefined} [descending=false]
5809
6883
  * */
5810
6884
 
5811
6885
  /**
@@ -5820,7 +6894,7 @@ const ColumnWidthMode = {
5820
6894
  };
5821
6895
 
5822
6896
  /**
5823
- * @enum {DGTable.Width|String|undefined}
6897
+ * @enum {DGTable.Width|string|undefined}
5824
6898
  * @const
5825
6899
  * @typedef {DGTable.Width}
5826
6900
  */
@@ -5833,57 +6907,58 @@ DGTable.Width = {
5833
6907
  /**
5834
6908
  * @expose
5835
6909
  * @typedef {Object} COLUMN_SORT_OPTIONS
5836
- * @property {String|null|undefined} column
5837
- * @property {Boolean|null|undefined} [descending=false]
6910
+ * @property {string|null|undefined} column
6911
+ * @property {boolean|null|undefined} [descending=false]
5838
6912
  * */
5839
6913
 
5840
6914
  /**
5841
6915
  * @expose
5842
6916
  * @typedef {Object} COLUMN_OPTIONS
5843
- * @property {String|null|undefined} width
5844
- * @property {String|null|undefined} name
5845
- * @property {String|null|undefined} label
5846
- * @property {String|null|undefined} dataPath - defaults to `name`
5847
- * @property {String|null|undefined} comparePath - defaults to `dataPath`
5848
- * @property {Number|String|null|undefined} comparePath
5849
- * @property {Boolean|null|undefined} [resizable=true]
5850
- * @property {Boolean|null|undefined} [movable=true]
5851
- * @property {Boolean|null|undefined} [sortable=true]
5852
- * @property {Boolean|null|undefined} [visible=true]
5853
- * @property {String|null|undefined} [cellClasses]
5854
- * @property {Boolean|null|undefined} [ignoreMin=false]
6917
+ * @property {string|null|undefined} width
6918
+ * @property {string|null|undefined} name
6919
+ * @property {string|null|undefined} label
6920
+ * @property {string|null|undefined} dataPath - defaults to `name`
6921
+ * @property {string|null|undefined} comparePath - defaults to `dataPath`
6922
+ * @property {number|string|null|undefined} comparePath
6923
+ * @property {boolean|null|undefined} [resizable=true]
6924
+ * @property {boolean|null|undefined} [movable=true]
6925
+ * @property {boolean|null|undefined} [sortable=true]
6926
+ * @property {boolean|null|undefined} [visible=true]
6927
+ * @property {string|null|undefined} [cellClasses]
6928
+ * @property {boolean|null|undefined} [ignoreMin=false]
5855
6929
  * */
5856
6930
 
5857
6931
  /**
5858
6932
  * @typedef {Object} DGTable.Options
5859
6933
  * @property {COLUMN_OPTIONS[]} [columns]
5860
- * @property {Number} [height]
6934
+ * @property {number} [height]
5861
6935
  * @property {DGTable.Width} [width]
5862
- * @property {Boolean|null|undefined} [virtualTable=true]
5863
- * @property {Boolean|null|undefined} [resizableColumns=true]
5864
- * @property {Boolean|null|undefined} [movableColumns=true]
5865
- * @property {Number|null|undefined} [sortableColumns=1]
5866
- * @property {Boolean|null|undefined} [adjustColumnWidthForSortArrow=true]
5867
- * @property {Boolean|null|undefined} [relativeWidthGrowsToFillWidth=true]
5868
- * @property {Boolean|null|undefined} [relativeWidthShrinksToFillWidth=false]
5869
- * @property {Boolean|null|undefined} [convertColumnWidthsToRelative=false]
5870
- * @property {Boolean|null|undefined} [autoFillTableWidth=false]
5871
- * @property {String|null|undefined} [cellClasses]
5872
- * @property {String|String[]|COLUMN_SORT_OPTIONS|COLUMN_SORT_OPTIONS[]} [sortColumn]
6936
+ * @property {boolean|null|undefined} [virtualTable=true]
6937
+ * @property {number|null|undefined} [estimatedRowHeight=40]
6938
+ * @property {boolean|null|undefined} [resizableColumns=true]
6939
+ * @property {boolean|null|undefined} [movableColumns=true]
6940
+ * @property {number|null|undefined} [sortableColumns=1]
6941
+ * @property {boolean|null|undefined} [adjustColumnWidthForSortArrow=true]
6942
+ * @property {boolean|null|undefined} [relativeWidthGrowsToFillWidth=true]
6943
+ * @property {boolean|null|undefined} [relativeWidthShrinksToFillWidth=false]
6944
+ * @property {boolean|null|undefined} [convertColumnWidthsToRelative=false]
6945
+ * @property {boolean|null|undefined} [autoFillTableWidth=false]
6946
+ * @property {string|null|undefined} [cellClasses]
6947
+ * @property {string|string[]|COLUMN_SORT_OPTIONS|COLUMN_SORT_OPTIONS[]} [sortColumn]
5873
6948
  * @property {Function|null|undefined} [cellFormatter=null]
5874
6949
  * @property {Function|null|undefined} [headerCellFormatter=null]
5875
- * @property {Number|null|undefined} [rowsBufferSize=10]
5876
- * @property {Number|null|undefined} [minColumnWidth=35]
5877
- * @property {Number|null|undefined} [resizeAreaWidth=8]
6950
+ * @property {number|null|undefined} [rowsBufferSize=10]
6951
+ * @property {number|null|undefined} [minColumnWidth=35]
6952
+ * @property {number|null|undefined} [resizeAreaWidth=8]
5878
6953
  * @property {{function(string,boolean):{function(a:*,b:*):boolean}}} [onComparatorRequired]
5879
- * @property {String|null|undefined} [resizerClassName=undefined]
5880
- * @property {String|null|undefined} [tableClassName=undefined]
5881
- * @property {Boolean|null|undefined} [allowCellPreview=true]
5882
- * @property {Boolean|null|undefined} [allowHeaderCellPreview=true]
5883
- * @property {String|null|undefined} [cellPreviewClassName=undefined]
5884
- * @property {Boolean|null|undefined} [cellPreviewAutoBackground=true]
6954
+ * @property {string|null|undefined} [resizerClassName=undefined]
6955
+ * @property {string|null|undefined} [tableClassName=undefined]
6956
+ * @property {boolean|null|undefined} [allowCellPreview=true]
6957
+ * @property {boolean|null|undefined} [allowHeaderCellPreview=true]
6958
+ * @property {string|null|undefined} [cellPreviewClassName=undefined]
6959
+ * @property {boolean|null|undefined} [cellPreviewAutoBackground=true]
5885
6960
  * @property {Element|null|undefined} [el=undefined]
5886
- * @property {String|null|undefined} [className=undefined]
6961
+ * @property {string|null|undefined} [className=undefined]
5887
6962
  * @property {Function|null|undefined} [filter=undefined]
5888
6963
  * */
5889
6964
 
@@ -5892,13 +6967,13 @@ DGTable.Width = {
5892
6967
  * currentTarget: Element,
5893
6968
  * data: Object.<string, *>,
5894
6969
  * delegateTarget: Element,
5895
- * isDefaultPrevented: Boolean,
5896
- * isImmediatePropagationStopped: Boolean,
5897
- * isPropagationStopped: Boolean,
6970
+ * isDefaultPrevented: boolean,
6971
+ * isImmediatePropagationStopped: boolean,
6972
+ * isPropagationStopped: boolean,
5898
6973
  * namespace: string,
5899
6974
  * originalEvent: MouseEvent|TouchEvent|Event,
5900
- * pageX: Number,
5901
- * pageY: Number,
6975
+ * pageX: number,
6976
+ * pageY: number,
5902
6977
  * preventDefault: Function,
5903
6978
  * props: Object.<string, *>,
5904
6979
  * relatedTarget: Element,
@@ -5906,9 +6981,9 @@ DGTable.Width = {
5906
6981
  * stopImmediatePropagation: Function,
5907
6982
  * stopPropagation: Function,
5908
6983
  * target: Element,
5909
- * timeStamp: Number,
6984
+ * timeStamp: number,
5910
6985
  * type: string,
5911
- * which: Number
6986
+ * which: number
5912
6987
  * }} jQuery_Event
5913
6988
  * */
5914
6989