@beyondwork/docx-react-component 1.0.81 → 1.0.82
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.
- package/package.json +1 -1
- package/src/api/public-types.ts +2 -1
- package/src/api/v3/_runtime-handle.ts +4 -0
- package/src/api/v3/runtime/document.ts +61 -3
- package/src/api/v3/runtime/review.ts +55 -2
- package/src/io/normalize/normalize-text.ts +4 -1
- package/src/io/ooxml/parse-drawing.ts +4 -0
- package/src/model/canonical-document.ts +2 -0
- package/src/ui/WordReviewEditor.tsx +71 -1
- package/src/ui-tailwind/chrome/editor-action-registry.ts +220 -0
- package/src/ui-tailwind/chrome/editor-actions-to-palette.ts +59 -35
- package/src/ui-tailwind/chrome-overlay/tw-chrome-overlay.tsx +1 -0
- package/src/ui-tailwind/chrome-overlay/tw-page-stack-overlay-layer.tsx +256 -37
- package/src/ui-tailwind/editor-surface/pm-schema.ts +54 -1
- package/src/ui-tailwind/editor-surface/tw-page-block-view.helpers.ts +31 -1
- package/src/ui-tailwind/editor-surface/tw-page-block-view.tsx +15 -0
- package/src/ui-tailwind/page-stack/tw-floating-image-layer.tsx +24 -5
- package/src/ui-tailwind/page-stack/tw-page-stack-chrome-layer.tsx +35 -6
- package/src/ui-tailwind/page-stack/use-visible-block-range.ts +333 -43
- package/src/ui-tailwind/review-workspace/use-page-markers.ts +273 -24
- package/src/ui-tailwind/theme/editor-theme.css +3 -5
- package/src/ui-tailwind/tw-review-workspace.tsx +3 -0
|
@@ -15,9 +15,10 @@ const ESTIMATED_BLOCKS_PER_PAGE_FALLBACK = 50;
|
|
|
15
15
|
* rendered in PM as "real" (non-placeholder) blocks.
|
|
16
16
|
*
|
|
17
17
|
* Sources of truth:
|
|
18
|
-
* 1.
|
|
19
|
-
* 2.
|
|
20
|
-
* 3.
|
|
18
|
+
* 1. Warm path: geometry page frames + layout page offsets.
|
|
19
|
+
* 2. Degraded path: IntersectionObserver on `[data-page-frame]` markers.
|
|
20
|
+
* 3. Selection head block-index — always included (selection-guard).
|
|
21
|
+
* 4. Overscan — ±N pages around the visible set to avoid jank when scrolling.
|
|
21
22
|
*
|
|
22
23
|
* Contract: the hook returns a **list of disjoint intervals**, not a single
|
|
23
24
|
* contiguous range. When the caret is far off-screen the hook emits the
|
|
@@ -60,6 +61,21 @@ export interface VisiblePageIndexRange {
|
|
|
60
61
|
end: number; // exclusive
|
|
61
62
|
}
|
|
62
63
|
|
|
64
|
+
export interface PageFrameForVisibility {
|
|
65
|
+
topPx: number;
|
|
66
|
+
heightPx: number;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export interface PageOffsetsForVisibility {
|
|
70
|
+
startOffset: number;
|
|
71
|
+
endOffset: number;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export interface BlockOffsetsForVisibility {
|
|
75
|
+
from: number;
|
|
76
|
+
to: number;
|
|
77
|
+
}
|
|
78
|
+
|
|
63
79
|
function readBlockIndex(el: HTMLElement, attr: string): number | null {
|
|
64
80
|
const v = el.getAttribute(attr);
|
|
65
81
|
if (v === null) return null;
|
|
@@ -67,6 +83,309 @@ function readBlockIndex(el: HTMLElement, attr: string): number | null {
|
|
|
67
83
|
return Number.isFinite(n) ? n : null;
|
|
68
84
|
}
|
|
69
85
|
|
|
86
|
+
function clampPageRange(
|
|
87
|
+
range: VisiblePageIndexRange,
|
|
88
|
+
pageCount: number,
|
|
89
|
+
): VisiblePageIndexRange | null {
|
|
90
|
+
const start = Math.max(0, Math.min(range.start, pageCount));
|
|
91
|
+
const end = Math.max(start, Math.min(range.end, pageCount));
|
|
92
|
+
return start < end ? { start, end } : null;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function initialLoadRange(totalBlockCount: number, overscanPages: number): readonly BlockRange[] {
|
|
96
|
+
const initialEnd = Math.min(
|
|
97
|
+
totalBlockCount,
|
|
98
|
+
(overscanPages * 2 + 1) * ESTIMATED_BLOCKS_PER_PAGE_FALLBACK,
|
|
99
|
+
);
|
|
100
|
+
return initialEnd > 0 ? [{ start: 0, end: initialEnd }] : [];
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function resolveBlockRangeForPageRange(input: {
|
|
104
|
+
pageMarkers: readonly HTMLElement[];
|
|
105
|
+
visiblePageIndexRange: VisiblePageIndexRange;
|
|
106
|
+
totalBlockCount: number;
|
|
107
|
+
}): BlockRange | null {
|
|
108
|
+
const { pageMarkers, visiblePageIndexRange, totalBlockCount } = input;
|
|
109
|
+
const normalized = clampPageRange(visiblePageIndexRange, pageMarkers.length);
|
|
110
|
+
if (!normalized) return null;
|
|
111
|
+
|
|
112
|
+
let minBlock = Infinity;
|
|
113
|
+
let maxBlock = -Infinity;
|
|
114
|
+
for (let pageIndex = normalized.start; pageIndex < normalized.end; pageIndex += 1) {
|
|
115
|
+
const marker = pageMarkers[pageIndex];
|
|
116
|
+
if (!marker) continue;
|
|
117
|
+
const first = readBlockIndex(marker, "data-page-first-block-index");
|
|
118
|
+
const last = readBlockIndex(marker, "data-page-last-block-index");
|
|
119
|
+
if (first !== null) minBlock = Math.min(minBlock, first);
|
|
120
|
+
if (last !== null) maxBlock = Math.max(maxBlock, last + 1);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (minBlock === Infinity) return null;
|
|
124
|
+
const range = {
|
|
125
|
+
start: Math.max(0, minBlock),
|
|
126
|
+
end: Math.min(totalBlockCount, maxBlock),
|
|
127
|
+
};
|
|
128
|
+
return range.end > range.start ? range : null;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function resolveSelectionRange(input: {
|
|
132
|
+
pageMarkers: readonly HTMLElement[];
|
|
133
|
+
selectionBlockIndex: number;
|
|
134
|
+
totalBlockCount: number;
|
|
135
|
+
}): BlockRange {
|
|
136
|
+
const { pageMarkers, selectionBlockIndex, totalBlockCount } = input;
|
|
137
|
+
let selStart = selectionBlockIndex;
|
|
138
|
+
let selEnd = selectionBlockIndex + 1;
|
|
139
|
+
for (const marker of pageMarkers) {
|
|
140
|
+
const first = readBlockIndex(marker, "data-page-first-block-index");
|
|
141
|
+
const last = readBlockIndex(marker, "data-page-last-block-index");
|
|
142
|
+
if (
|
|
143
|
+
first !== null &&
|
|
144
|
+
last !== null &&
|
|
145
|
+
selectionBlockIndex >= first &&
|
|
146
|
+
selectionBlockIndex <= last
|
|
147
|
+
) {
|
|
148
|
+
selStart = first;
|
|
149
|
+
selEnd = last + 1;
|
|
150
|
+
break;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return {
|
|
154
|
+
start: Math.max(0, selStart),
|
|
155
|
+
end: Math.min(totalBlockCount, selEnd),
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function resolveBlockRangeFromOffsetSpan(input: {
|
|
160
|
+
blocks: readonly BlockOffsetsForVisibility[];
|
|
161
|
+
startOffset: number;
|
|
162
|
+
endOffset: number;
|
|
163
|
+
totalBlockCount: number;
|
|
164
|
+
}): BlockRange | null {
|
|
165
|
+
const { blocks, startOffset, endOffset, totalBlockCount } = input;
|
|
166
|
+
if (endOffset <= startOffset) return null;
|
|
167
|
+
|
|
168
|
+
let first = -1;
|
|
169
|
+
let last = -1;
|
|
170
|
+
const scanCount = Math.min(blocks.length, totalBlockCount);
|
|
171
|
+
for (let index = 0; index < scanCount; index += 1) {
|
|
172
|
+
const block = blocks[index];
|
|
173
|
+
if (!block) continue;
|
|
174
|
+
if (block.from >= endOffset) break;
|
|
175
|
+
if (block.from >= startOffset && block.from < endOffset) {
|
|
176
|
+
if (first < 0) first = index;
|
|
177
|
+
last = index;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
if (first < 0 || last < first) return null;
|
|
181
|
+
return { start: first, end: last + 1 };
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
function resolveSelectionRangeFromPageOffsets(input: {
|
|
185
|
+
blocks: readonly BlockOffsetsForVisibility[];
|
|
186
|
+
pageCount: number;
|
|
187
|
+
getPageOffsets: (pageIndex: number) => PageOffsetsForVisibility | null;
|
|
188
|
+
selectionBlockIndex: number;
|
|
189
|
+
totalBlockCount: number;
|
|
190
|
+
}): BlockRange {
|
|
191
|
+
const {
|
|
192
|
+
blocks,
|
|
193
|
+
pageCount,
|
|
194
|
+
getPageOffsets,
|
|
195
|
+
selectionBlockIndex,
|
|
196
|
+
totalBlockCount,
|
|
197
|
+
} = input;
|
|
198
|
+
const selectionBlock = blocks[selectionBlockIndex];
|
|
199
|
+
if (!selectionBlock) {
|
|
200
|
+
return {
|
|
201
|
+
start: Math.max(0, selectionBlockIndex),
|
|
202
|
+
end: Math.min(totalBlockCount, selectionBlockIndex + 1),
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
for (let pageIndex = 0; pageIndex < pageCount; pageIndex += 1) {
|
|
207
|
+
const page = getPageOffsets(pageIndex);
|
|
208
|
+
if (!page) continue;
|
|
209
|
+
if (selectionBlock.from >= page.startOffset && selectionBlock.from < page.endOffset) {
|
|
210
|
+
const pageRange = resolveBlockRangeFromOffsetSpan({
|
|
211
|
+
blocks,
|
|
212
|
+
startOffset: page.startOffset,
|
|
213
|
+
endOffset: page.endOffset,
|
|
214
|
+
totalBlockCount,
|
|
215
|
+
});
|
|
216
|
+
if (pageRange) return pageRange;
|
|
217
|
+
break;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
return {
|
|
222
|
+
start: Math.max(0, selectionBlockIndex),
|
|
223
|
+
end: Math.min(totalBlockCount, selectionBlockIndex + 1),
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
function withSelectionGuard(input: {
|
|
228
|
+
viewportRange: BlockRange;
|
|
229
|
+
selectionBlockIndex: number | null;
|
|
230
|
+
resolveSelectionRange: (selectionBlockIndex: number) => BlockRange;
|
|
231
|
+
}): readonly BlockRange[] {
|
|
232
|
+
const {
|
|
233
|
+
viewportRange,
|
|
234
|
+
selectionBlockIndex,
|
|
235
|
+
resolveSelectionRange: resolveSelectionRangeForIndex,
|
|
236
|
+
} = input;
|
|
237
|
+
if (
|
|
238
|
+
selectionBlockIndex === null ||
|
|
239
|
+
(selectionBlockIndex >= viewportRange.start && selectionBlockIndex < viewportRange.end)
|
|
240
|
+
) {
|
|
241
|
+
return viewportRange.end > viewportRange.start ? [viewportRange] : [];
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
const selectionRange = resolveSelectionRangeForIndex(selectionBlockIndex);
|
|
245
|
+
if (selectionRange.end <= selectionRange.start) {
|
|
246
|
+
return viewportRange.end > viewportRange.start ? [viewportRange] : [];
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
return selectionRange.start < viewportRange.start
|
|
250
|
+
? [selectionRange, viewportRange]
|
|
251
|
+
: [viewportRange, selectionRange];
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
export function resolveVisibleBlockRangesFromPageRange(input: {
|
|
255
|
+
pageMarkers: readonly HTMLElement[];
|
|
256
|
+
visiblePageIndexRange: VisiblePageIndexRange;
|
|
257
|
+
selectionBlockIndex: number | null;
|
|
258
|
+
totalBlockCount: number;
|
|
259
|
+
}): readonly BlockRange[] | null {
|
|
260
|
+
if (input.totalBlockCount <= 0) return [];
|
|
261
|
+
const viewportRange = resolveBlockRangeForPageRange(input);
|
|
262
|
+
if (!viewportRange) return null;
|
|
263
|
+
return withSelectionGuard({
|
|
264
|
+
viewportRange,
|
|
265
|
+
selectionBlockIndex: input.selectionBlockIndex,
|
|
266
|
+
resolveSelectionRange: (selectionBlockIndex) =>
|
|
267
|
+
resolveSelectionRange({
|
|
268
|
+
pageMarkers: input.pageMarkers,
|
|
269
|
+
selectionBlockIndex,
|
|
270
|
+
totalBlockCount: input.totalBlockCount,
|
|
271
|
+
}),
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
export function resolveVisibleBlockRangesFromPageOffsets(input: {
|
|
276
|
+
blocks: readonly BlockOffsetsForVisibility[];
|
|
277
|
+
pageCount: number;
|
|
278
|
+
visiblePageIndexRange: VisiblePageIndexRange;
|
|
279
|
+
selectionBlockIndex: number | null;
|
|
280
|
+
totalBlockCount: number;
|
|
281
|
+
getPageOffsets: (pageIndex: number) => PageOffsetsForVisibility | null;
|
|
282
|
+
}): readonly BlockRange[] | null {
|
|
283
|
+
const {
|
|
284
|
+
blocks,
|
|
285
|
+
pageCount,
|
|
286
|
+
visiblePageIndexRange,
|
|
287
|
+
selectionBlockIndex,
|
|
288
|
+
totalBlockCount,
|
|
289
|
+
getPageOffsets,
|
|
290
|
+
} = input;
|
|
291
|
+
if (totalBlockCount <= 0) return [];
|
|
292
|
+
const normalized = clampPageRange(visiblePageIndexRange, pageCount);
|
|
293
|
+
if (!normalized) return null;
|
|
294
|
+
|
|
295
|
+
let startOffset = Infinity;
|
|
296
|
+
let endOffset = -Infinity;
|
|
297
|
+
for (let pageIndex = normalized.start; pageIndex < normalized.end; pageIndex += 1) {
|
|
298
|
+
const page = getPageOffsets(pageIndex);
|
|
299
|
+
if (!page) continue;
|
|
300
|
+
if (page.endOffset <= page.startOffset) continue;
|
|
301
|
+
startOffset = Math.min(startOffset, page.startOffset);
|
|
302
|
+
endOffset = Math.max(endOffset, page.endOffset);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
if (startOffset === Infinity || endOffset <= startOffset) return null;
|
|
306
|
+
const viewportRange = resolveBlockRangeFromOffsetSpan({
|
|
307
|
+
blocks,
|
|
308
|
+
startOffset,
|
|
309
|
+
endOffset,
|
|
310
|
+
totalBlockCount,
|
|
311
|
+
});
|
|
312
|
+
if (!viewportRange) return null;
|
|
313
|
+
|
|
314
|
+
return withSelectionGuard({
|
|
315
|
+
viewportRange,
|
|
316
|
+
selectionBlockIndex,
|
|
317
|
+
resolveSelectionRange: (selectionBlockIndexForGuard) =>
|
|
318
|
+
resolveSelectionRangeFromPageOffsets({
|
|
319
|
+
blocks,
|
|
320
|
+
pageCount,
|
|
321
|
+
getPageOffsets,
|
|
322
|
+
selectionBlockIndex: selectionBlockIndexForGuard,
|
|
323
|
+
totalBlockCount,
|
|
324
|
+
}),
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
export function resolveVisiblePageIndexRangeFromViewport(input: {
|
|
329
|
+
pageCount: number;
|
|
330
|
+
viewportTopPx: number;
|
|
331
|
+
viewportHeightPx: number;
|
|
332
|
+
overscanPages: number;
|
|
333
|
+
getPageFrame: (pageIndex: number) => PageFrameForVisibility | null;
|
|
334
|
+
}): VisiblePageIndexRange | null {
|
|
335
|
+
const { pageCount, viewportTopPx, viewportHeightPx, overscanPages, getPageFrame } = input;
|
|
336
|
+
if (pageCount <= 0 || viewportHeightPx <= 0) return null;
|
|
337
|
+
|
|
338
|
+
const viewportBottomPx = viewportTopPx + viewportHeightPx;
|
|
339
|
+
let firstVisible = Infinity;
|
|
340
|
+
let lastVisible = -Infinity;
|
|
341
|
+
let nearestPageAfterViewport = -1;
|
|
342
|
+
let nearestPageAfterDistance = Infinity;
|
|
343
|
+
let lastPageBeforeViewport = -1;
|
|
344
|
+
let lastPageBeforeDistance = Infinity;
|
|
345
|
+
|
|
346
|
+
for (let pageIndex = 0; pageIndex < pageCount; pageIndex += 1) {
|
|
347
|
+
const frame = getPageFrame(pageIndex);
|
|
348
|
+
if (!frame) continue;
|
|
349
|
+
const pageTopPx = frame.topPx;
|
|
350
|
+
const pageBottomPx = frame.topPx + frame.heightPx;
|
|
351
|
+
if (pageBottomPx >= viewportTopPx && pageTopPx <= viewportBottomPx) {
|
|
352
|
+
firstVisible = Math.min(firstVisible, pageIndex);
|
|
353
|
+
lastVisible = Math.max(lastVisible, pageIndex);
|
|
354
|
+
}
|
|
355
|
+
if (pageBottomPx < viewportTopPx) {
|
|
356
|
+
lastPageBeforeViewport = pageIndex;
|
|
357
|
+
lastPageBeforeDistance = viewportTopPx - pageBottomPx;
|
|
358
|
+
} else if (nearestPageAfterViewport < 0 && pageTopPx > viewportBottomPx) {
|
|
359
|
+
nearestPageAfterViewport = pageIndex;
|
|
360
|
+
nearestPageAfterDistance = pageTopPx - viewportBottomPx;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
if (firstVisible === Infinity) {
|
|
365
|
+
const fallbackPage =
|
|
366
|
+
nearestPageAfterViewport >= 0 && lastPageBeforeViewport >= 0
|
|
367
|
+
? nearestPageAfterDistance < lastPageBeforeDistance
|
|
368
|
+
? nearestPageAfterViewport
|
|
369
|
+
: lastPageBeforeViewport
|
|
370
|
+
: nearestPageAfterViewport >= 0
|
|
371
|
+
? nearestPageAfterViewport
|
|
372
|
+
: lastPageBeforeViewport >= 0
|
|
373
|
+
? lastPageBeforeViewport
|
|
374
|
+
: -1;
|
|
375
|
+
if (fallbackPage < 0) return null;
|
|
376
|
+
firstVisible = fallbackPage;
|
|
377
|
+
lastVisible = fallbackPage;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
return clampPageRange(
|
|
381
|
+
{
|
|
382
|
+
start: firstVisible - overscanPages,
|
|
383
|
+
end: lastVisible + overscanPages + 1,
|
|
384
|
+
},
|
|
385
|
+
pageCount,
|
|
386
|
+
);
|
|
387
|
+
}
|
|
388
|
+
|
|
70
389
|
/**
|
|
71
390
|
* Multi-interval hook. Returns the list of non-overlapping block-index
|
|
72
391
|
* intervals that should be real in the surface projection. Typical output:
|
|
@@ -121,8 +440,7 @@ export function useVisibleBlockRanges(input: VisibleBlockRangeInput): readonly B
|
|
|
121
440
|
if (totalBlockCount <= 0) return [];
|
|
122
441
|
if (visiblePages.size === 0 && selectionBlockIndex === null) {
|
|
123
442
|
// No visibility signal yet — return initial-load window (first 2 × overscanPages worth).
|
|
124
|
-
|
|
125
|
-
return initialEnd > 0 ? [{ start: 0, end: initialEnd }] : [];
|
|
443
|
+
return initialLoadRange(totalBlockCount, overscanPages);
|
|
126
444
|
}
|
|
127
445
|
|
|
128
446
|
// Expand visiblePages by ±overscanPages.
|
|
@@ -158,48 +476,20 @@ export function useVisibleBlockRanges(input: VisibleBlockRangeInput): readonly B
|
|
|
158
476
|
// to cover the gap. On long documents with the caret far from the
|
|
159
477
|
// viewport this avoids realizing the entire gap as real blocks (the
|
|
160
478
|
// pre-fix behavior that dominated steady-state scroll cost).
|
|
161
|
-
if (
|
|
162
|
-
selectionBlockIndex === null ||
|
|
163
|
-
(selectionBlockIndex >= viewportRange.start &&
|
|
164
|
-
selectionBlockIndex < viewportRange.end)
|
|
165
|
-
) {
|
|
166
|
-
return viewportRange.end > viewportRange.start ? [viewportRange] : [];
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
// Resolve the page that contains the selection.
|
|
170
|
-
let selStart = selectionBlockIndex;
|
|
171
|
-
let selEnd = selectionBlockIndex + 1;
|
|
172
|
-
for (const marker of pageMarkers) {
|
|
173
|
-
const first = readBlockIndex(marker, "data-page-first-block-index");
|
|
174
|
-
const last = readBlockIndex(marker, "data-page-last-block-index");
|
|
175
|
-
if (
|
|
176
|
-
first !== null &&
|
|
177
|
-
last !== null &&
|
|
178
|
-
selectionBlockIndex >= first &&
|
|
179
|
-
selectionBlockIndex <= last
|
|
180
|
-
) {
|
|
181
|
-
selStart = first;
|
|
182
|
-
selEnd = last + 1;
|
|
183
|
-
break;
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
const selectionRange: BlockRange = {
|
|
187
|
-
start: Math.max(0, selStart),
|
|
188
|
-
end: Math.min(totalBlockCount, selEnd),
|
|
189
|
-
};
|
|
190
|
-
if (selectionRange.end <= selectionRange.start) {
|
|
191
|
-
return viewportRange.end > viewportRange.start ? [viewportRange] : [];
|
|
192
|
-
}
|
|
193
|
-
|
|
194
479
|
// Sort ascending by `start` so the facet layer sees a canonical order
|
|
195
480
|
// and can dedupe with a simple serialization. Runtime's
|
|
196
481
|
// `normalizeViewportRanges` merges touching/overlapping intervals, so
|
|
197
482
|
// we don't need to handle that here.
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
483
|
+
return withSelectionGuard({
|
|
484
|
+
viewportRange,
|
|
485
|
+
selectionBlockIndex,
|
|
486
|
+
resolveSelectionRange: (selectionBlockIndexForGuard) =>
|
|
487
|
+
resolveSelectionRange({
|
|
488
|
+
pageMarkers,
|
|
489
|
+
selectionBlockIndex: selectionBlockIndexForGuard,
|
|
490
|
+
totalBlockCount,
|
|
491
|
+
}),
|
|
492
|
+
});
|
|
203
493
|
}, [visiblePages, selectionBlockIndex, pageMarkers, overscanPages, totalBlockCount]);
|
|
204
494
|
}
|
|
205
495
|
|