editor: only page notes past a size threshold

This commit is contained in:
Ammar Ahmed
2026-08-21 12:35:40 +05:00
parent ed1a6d2e87
commit 0d2caed4b9
2 changed files with 19 additions and 4 deletions

View File

@@ -22,12 +22,17 @@ import { HeightMap } from "./height-map.js";
import { withVirtualization } from "./node-views.js";
import { virtualizationPlugin } from "./viewport-plugin.js";
/** Paging only engages for notes larger than this many top-level blocks. */
const DEFAULT_THRESHOLD_BLOCKS = 300;
export type VirtualizationOptions = {
enabled: boolean;
thresholdBlocks: number;
};
export type VirtualizationStorage = {
enabled: boolean;
thresholdBlocks: number;
heightMap: HeightMap;
};
@@ -44,12 +49,13 @@ export const Virtualization = Extension.create<VirtualizationOptions>({
name: "virtualization",
addOptions() {
return { enabled: false };
return { enabled: false, thresholdBlocks: DEFAULT_THRESHOLD_BLOCKS };
},
addStorage(): VirtualizationStorage {
return {
enabled: this.options.enabled,
thresholdBlocks: this.options.thresholdBlocks,
heightMap: new HeightMap()
};
},
@@ -87,7 +93,11 @@ export function installVirtualization(editor: Editor): void {
Object.defineProperty(editor.extensionManager, "nodeViews", {
configurable: true,
get() {
return withVirtualization(originalGetter.call(this), storage.heightMap);
return withVirtualization(
originalGetter.call(this),
storage.heightMap,
storage.thresholdBlocks
);
}
});
}

View File

@@ -172,7 +172,8 @@ function wrapCustom(
export function withVirtualization(
nodeViews: Record<string, NodeViewConstructor>,
heightMap: HeightMap
heightMap: HeightMap,
thresholdBlocks: number
): Record<string, NodeViewConstructor> {
const wrapped: Record<string, NodeViewConstructor> = { ...nodeViews };
@@ -182,9 +183,13 @@ export function withVirtualization(
const topLevel = isTopLevel(view, getPos as () => number | undefined);
const materialize = isMaterialized(decorations);
// Only page documents past the size threshold. Smaller notes — the
// overwhelming majority — render fully and are unaffected by any of this.
const belowThreshold = view.state.doc.childCount <= thresholdBlocks;
// Nested instances (inside callouts, tables, list items) are never
// virtualized — only the outermost blocks are paged.
if (!topLevel) {
if (!topLevel || belowThreshold) {
return inner
? inner(node, view, getPos, decorations, innerDecorations)
: createMaterializedDefault(node, heightMap);