Skip to content

Commit 58793cd

Browse files
committed
Instance column size CSS and general stylesheet optimization
1 parent 6e99f43 commit 58793cd

6 files changed

Lines changed: 266 additions & 100 deletions

File tree

src/ts/events.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,17 @@ export class RegularViewEventModel extends RegularVirtualTableViewModel {
5656
*/
5757
async _on_scroll(event: Event) {
5858
event.stopPropagation();
59+
if (this._scroll_pending) {
60+
return;
61+
}
62+
63+
this._scroll_pending = true;
64+
try {
65+
await new Promise(requestAnimationFrame);
66+
} finally {
67+
this._scroll_pending = false;
68+
}
69+
5970
await this.draw({ invalid_viewport: false, cache: true });
6071
this.dispatchEvent(new CustomEvent<undefined>("regular-table-scroll"));
6172
}
@@ -221,6 +232,7 @@ export class RegularViewEventModel extends RegularVirtualTableViewModel {
221232
}
222233

223234
td.classList.remove("rt-cell-clip");
235+
this.table_model.body._untagColumn(td);
224236
}
225237
}
226238

@@ -372,11 +384,17 @@ export class RegularViewEventModel extends RegularVirtualTableViewModel {
372384
// Update header clipping class
373385
th.classList.toggle("rt-cell-clip", should_clip);
374386

375-
// Update body cell clipping classes
387+
// Update body cell clipping classes. Clipped cells must carry the
388+
// column tag so the override's `max-width` clamp reaches them.
376389
for (const row of this.table_model.body.cells) {
377390
const td = row[virtual_x];
378391
if (td) {
379392
td.classList.toggle("rt-cell-clip", should_clip);
393+
if (should_clip) {
394+
this.table_model.body._tagColumn(td, size_key);
395+
} else {
396+
this.table_model.body._untagColumn(td);
397+
}
380398
}
381399
}
382400
}

src/ts/scroll_panel.ts

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import { DEBUG, BROWSER_MAX_HEIGHT } from "./constants";
1414
import type { RegularTableViewModel } from "./table";
1515
import { RegularTableElement } from "./regular-table";
1616
import {
17-
CellTuple,
1817
ColumnSizes,
1918
StyleCallback,
2019
ContainerSize,
@@ -95,6 +94,7 @@ export class RegularVirtualTableViewModel extends HTMLElement {
9594
protected _is_styling?: boolean;
9695
protected table_model!: RegularTableViewModel;
9796
protected _style_callbacks!: Array<StyleCallback>;
97+
protected _scroll_pending?: boolean;
9898
private _probe_element?: [HTMLElement, HTMLElement];
9999

100100
/**
@@ -121,7 +121,11 @@ export class RegularVirtualTableViewModel extends HTMLElement {
121121
* Await any pending rendering operations.
122122
*/
123123
async flush(): Promise<void> {
124-
await flush_tag(this);
124+
// A scroll-driven draw may still be waiting on its animation frame
125+
// (see `_on_scroll`); keep flushing until none is pending.
126+
do {
127+
await flush_tag(this);
128+
} while (this._scroll_pending);
125129
}
126130

127131
/**
@@ -309,10 +313,7 @@ export class RegularVirtualTableViewModel extends HTMLElement {
309313
*
310314
* @param viewport
311315
*/
312-
protected _update_sub_cell_offset(
313-
viewport: Viewport,
314-
last_cell?: CellTuple,
315-
): void {
316+
protected _update_sub_cell_offset(viewport: Viewport): void {
316317
const y_offset =
317318
(this._column_sizes.row_height || 0) * (viewport.start_row % 1) ||
318319
0;
@@ -321,13 +322,9 @@ export class RegularVirtualTableViewModel extends HTMLElement {
321322
(this.table_model._row_headers_length || 0) +
322323
Math.floor(viewport.start_col);
323324

324-
if (this._column_sizes.indices[x_offset_index] === undefined) {
325-
this._column_sizes.indices[x_offset_index] =
326-
last_cell?.[0]?.offsetWidth || 0;
327-
}
328-
329325
const x_offset =
330-
this._column_sizes.indices[x_offset_index]! *
326+
(this._column_sizes.indices[x_offset_index] ??
327+
this.table_model._estimated_column_width()) *
331328
(viewport.start_col % 1) || 0;
332329

333330
this._sub_cell_rule.style.setProperty(CLIP_X, `${x_offset}px`);
@@ -592,12 +589,12 @@ async function internal_draw(
592589
preserve_width,
593590
viewport,
594591
safe_num_columns,
595-
async (last_cells) => {
592+
async () => {
596593
// We want to perform this before the next event loop so there
597594
// is no scroll jitter, but only on the first iteration as
598595
// subsequent viewports are incorrect.
599596
if (first_iteration) {
600-
this._update_sub_cell_offset(viewport, last_cells);
597+
this._update_sub_cell_offset(viewport);
601598
first_iteration = false;
602599
}
603600

@@ -607,6 +604,10 @@ async function internal_draw(
607604
},
608605
);
609606

607+
// Re-apply with post-measurement widths, in case the first
608+
// application used an estimate for a never-measured leading column.
609+
this._update_sub_cell_offset(viewport);
610+
610611
const old_height = this._column_sizes.row_height;
611612
this.table_model.header.reset_header_cache();
612613
if (old_height !== this._column_sizes.row_height) {

0 commit comments

Comments
 (0)