(core) Fix issue when using Other Values with many rows

Summary:
Fix an error that used to happen on Chrome: `RangeError: Maximum call stack size
exceeded`. Happened when clicking the `Other Values` checkbox when
filtering a large table. Turns out culprit was a function call that
was using a spread operator to pass a large number of argument to a
function.

Spread operator for passing multiple argument must not be used with
too many arguments. Otherwise it could hit the engine's argument
length limit. That limit varies across browser (webkit's
javascriptcore engine has argument limit of 65536).

Some interesting description of the limit can be found here:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply#using_apply_and_built-in_functions

In order to get the fix fast, implementing a proper test for it is left for a follow-up commit.

Test Plan:
 - Manually tested on Chrome/FF

Reviewers: paulfitz

Reviewed By: paulfitz

Subscribers: paulfitz

Differential Revision: https://phab.getgrist.com/D2779
This commit is contained in:
Cyprien P 2021-04-19 22:55:46 +02:00
parent 2dfa427d63
commit 8a26550312
2 changed files with 12 additions and 4 deletions

View File

@ -85,14 +85,22 @@ export class ColumnFilter extends Disposable {
return this._values.has(val) === this._include;
}
public add(...values: CellValue[]) {
public add(val: CellValue) {
this.addMany([val]);
}
public addMany(values: CellValue[]) {
for (const val of values) {
this._include ? this._values.add(val) : this._values.delete(val);
}
this._updateState();
}
public delete(...values: CellValue[]) {
public delete(val: CellValue) {
this.deleteMany([val]);
}
public deleteMany(values: CellValue[]) {
for (const val of values) {
this._include ? this._values.delete(val) : this._values.add(val);
}

View File

@ -204,9 +204,9 @@ class BeyondLimit extends Disposable implements SummaryModel {
public callback(checked: boolean) {
const keys = this.model.valuesBeyondLimit.get().map(([key, _val]) => key);
if (checked) {
this.columnFilter.add(...keys);
this.columnFilter.addMany(keys);
} else {
this.columnFilter.delete(...keys);
this.columnFilter.deleteMany(keys);
}
}
}