Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion src/ts/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,17 @@ export class RegularViewEventModel extends RegularVirtualTableViewModel {
*/
async _on_scroll(event: Event) {
event.stopPropagation();
if (this._scroll_pending) {
return;
}

this._scroll_pending = true;
try {
await new Promise(requestAnimationFrame);
} finally {
this._scroll_pending = false;
}

await this.draw({ invalid_viewport: false, cache: true });
this.dispatchEvent(new CustomEvent<undefined>("regular-table-scroll"));
}
Expand Down Expand Up @@ -221,6 +232,7 @@ export class RegularViewEventModel extends RegularVirtualTableViewModel {
}

td.classList.remove("rt-cell-clip");
this.table_model.body._untagColumn(td);
}
}

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

// Update body cell clipping classes
// Update body cell clipping classes. Clipped cells must carry the
// column tag so the override's `max-width` clamp reaches them.
for (const row of this.table_model.body.cells) {
const td = row[virtual_x];
if (td) {
td.classList.toggle("rt-cell-clip", should_clip);
if (should_clip) {
this.table_model.body._tagColumn(td, size_key);
} else {
this.table_model.body._untagColumn(td);
}
}
}
}
Expand Down
29 changes: 15 additions & 14 deletions src/ts/scroll_panel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import { DEBUG, BROWSER_MAX_HEIGHT } from "./constants";
import type { RegularTableViewModel } from "./table";
import { RegularTableElement } from "./regular-table";
import {
CellTuple,
ColumnSizes,
StyleCallback,
ContainerSize,
Expand Down Expand Up @@ -95,6 +94,7 @@ export class RegularVirtualTableViewModel extends HTMLElement {
protected _is_styling?: boolean;
protected table_model!: RegularTableViewModel;
protected _style_callbacks!: Array<StyleCallback>;
protected _scroll_pending?: boolean;
private _probe_element?: [HTMLElement, HTMLElement];

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

/**
Expand Down Expand Up @@ -309,10 +313,7 @@ export class RegularVirtualTableViewModel extends HTMLElement {
*
* @param viewport
*/
protected _update_sub_cell_offset(
viewport: Viewport,
last_cell?: CellTuple,
): void {
protected _update_sub_cell_offset(viewport: Viewport): void {
const y_offset =
(this._column_sizes.row_height || 0) * (viewport.start_row % 1) ||
0;
Expand All @@ -321,13 +322,9 @@ export class RegularVirtualTableViewModel extends HTMLElement {
(this.table_model._row_headers_length || 0) +
Math.floor(viewport.start_col);

if (this._column_sizes.indices[x_offset_index] === undefined) {
this._column_sizes.indices[x_offset_index] =
last_cell?.[0]?.offsetWidth || 0;
}

const x_offset =
this._column_sizes.indices[x_offset_index]! *
(this._column_sizes.indices[x_offset_index] ??
this.table_model._estimated_column_width()) *
(viewport.start_col % 1) || 0;

this._sub_cell_rule.style.setProperty(CLIP_X, `${x_offset}px`);
Expand Down Expand Up @@ -592,12 +589,12 @@ async function internal_draw(
preserve_width,
viewport,
safe_num_columns,
async (last_cells) => {
async () => {
// We want to perform this before the next event loop so there
// is no scroll jitter, but only on the first iteration as
// subsequent viewports are incorrect.
if (first_iteration) {
this._update_sub_cell_offset(viewport, last_cells);
this._update_sub_cell_offset(viewport);
first_iteration = false;
}

Expand All @@ -607,6 +604,10 @@ async function internal_draw(
},
);

// Re-apply with post-measurement widths, in case the first
// application used an estimate for a never-measured leading column.
this._update_sub_cell_offset(viewport);

const old_height = this._column_sizes.row_height;
this.table_model.header.reset_header_cache();
if (old_height !== this._column_sizes.row_height) {
Expand Down
Loading
Loading