@beyondwork/docx-react-component 1.0.131 → 1.0.132
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/dist/api/public-types.cjs +679 -157
- package/dist/api/public-types.d.cts +2 -2
- package/dist/api/public-types.d.ts +2 -2
- package/dist/api/public-types.js +5 -3
- package/dist/api/v3.cjs +371 -32
- package/dist/api/v3.d.cts +3 -3
- package/dist/api/v3.d.ts +3 -3
- package/dist/api/v3.js +10 -10
- package/dist/{canonical-document-BMtONpgf.d.cts → canonical-document-CfZIc-fC.d.cts} +1 -1
- package/dist/{canonical-document-BMtONpgf.d.ts → canonical-document-CfZIc-fC.d.ts} +1 -1
- package/dist/{chunk-YLL7MF5C.js → chunk-43JAPM2F.js} +24 -17
- package/dist/{chunk-4YCWECLZ.js → chunk-4HGFJ6Z2.js} +1 -1
- package/dist/{chunk-HYHCRMR7.js → chunk-6736GA6J.js} +1 -1
- package/dist/{chunk-Q7Y57KOK.js → chunk-6TLZ6CMP.js} +2 -2
- package/dist/{chunk-DGA7M77X.js → chunk-ALWXYGXP.js} +2 -2
- package/dist/{chunk-PHMWH23E.js → chunk-C5LXKR54.js} +1 -1
- package/dist/{chunk-6TBLDBCL.js → chunk-CDEZGLQ3.js} +1 -1
- package/dist/{chunk-VRKK2CSZ.js → chunk-JVTDBX67.js} +2 -2
- package/dist/{chunk-THVM6EP5.js → chunk-LPLJZJT2.js} +1196 -35
- package/dist/{chunk-T5YYFDZB.js → chunk-N5FTU4HZ.js} +1 -1
- package/dist/{chunk-3YCQM2RV.js → chunk-QUTVR72L.js} +8 -7
- package/dist/{chunk-M7YRJX6V.js → chunk-RBWJHRNP.js} +1 -1
- package/dist/{chunk-A66ZVUAT.js → chunk-RYMMKOFI.js} +204 -10
- package/dist/{chunk-QXKQPUOM.js → chunk-SZ6BJA4Q.js} +3 -3
- package/dist/{chunk-A3GSNB4G.js → chunk-U3UMKA7B.js} +147 -13
- package/dist/{chunk-KNHMXKC6.js → chunk-UFPBYJMA.js} +2 -2
- package/dist/{chunk-35RHOE6I.js → chunk-UP2KDOYE.js} +6 -1162
- package/dist/{chunk-CI2TD3T4.js → chunk-W2I47J2Q.js} +1 -1
- package/dist/{chunk-7G5GR3VV.js → chunk-XYTWOJII.js} +5 -5
- package/dist/{chunk-WZDKNF37.js → chunk-YUHNDEV5.js} +7 -7
- package/dist/{chunk-ZVC23LKV.js → chunk-ZDYGRO2Z.js} +1 -1
- package/dist/compare.d.cts +1 -1
- package/dist/compare.d.ts +1 -1
- package/dist/core/commands/formatting-commands.d.cts +2 -2
- package/dist/core/commands/formatting-commands.d.ts +2 -2
- package/dist/core/commands/image-commands.cjs +312 -20
- package/dist/core/commands/image-commands.d.cts +2 -2
- package/dist/core/commands/image-commands.d.ts +2 -2
- package/dist/core/commands/image-commands.js +5 -5
- package/dist/core/commands/section-layout-commands.d.cts +2 -2
- package/dist/core/commands/section-layout-commands.d.ts +2 -2
- package/dist/core/commands/style-commands.d.cts +2 -2
- package/dist/core/commands/style-commands.d.ts +2 -2
- package/dist/core/commands/table-structure-commands.cjs +312 -20
- package/dist/core/commands/table-structure-commands.d.cts +2 -2
- package/dist/core/commands/table-structure-commands.d.ts +2 -2
- package/dist/core/commands/table-structure-commands.js +4 -4
- package/dist/core/commands/text-commands.cjs +312 -20
- package/dist/core/commands/text-commands.d.cts +2 -2
- package/dist/core/commands/text-commands.d.ts +2 -2
- package/dist/core/commands/text-commands.js +5 -5
- package/dist/core/selection/mapping.d.cts +2 -2
- package/dist/core/selection/mapping.d.ts +2 -2
- package/dist/core/state/editor-state.d.cts +2 -2
- package/dist/core/state/editor-state.d.ts +2 -2
- package/dist/index.cjs +3015 -2213
- package/dist/index.d.cts +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.js +554 -99
- package/dist/io/docx-session.d.cts +4 -4
- package/dist/io/docx-session.d.ts +4 -4
- package/dist/io/docx-session.js +4 -4
- package/dist/legal.d.cts +1 -1
- package/dist/legal.d.ts +1 -1
- package/dist/legal.js +3 -3
- package/dist/{loader-B-aL5HGD.d.ts → loader-CfpeEPAa.d.ts} +3 -3
- package/dist/{loader-DiY_ZgKl.d.cts → loader-MAa8VpzW.d.cts} +3 -3
- package/dist/{public-types-gvubspUI.d.cts → public-types-Cjs8glST.d.ts} +137 -2
- package/dist/{public-types-DyqnxxO9.d.ts → public-types-KBS6JnOs.d.cts} +137 -2
- package/dist/public-types.cjs +679 -157
- package/dist/public-types.d.cts +2 -2
- package/dist/public-types.d.ts +2 -2
- package/dist/public-types.js +5 -3
- package/dist/runtime/collab.d.cts +3 -3
- package/dist/runtime/collab.d.ts +3 -3
- package/dist/runtime/document-runtime.cjs +371 -22
- package/dist/runtime/document-runtime.d.cts +2 -2
- package/dist/runtime/document-runtime.d.ts +2 -2
- package/dist/runtime/document-runtime.js +14 -14
- package/dist/{session-CDB0hohT.d.ts → session-CkoH8FoY.d.ts} +3 -3
- package/dist/{session-BUN6B-Vj.d.cts → session-wwe0Gib-.d.cts} +3 -3
- package/dist/session.d.cts +5 -5
- package/dist/session.d.ts +5 -5
- package/dist/session.js +5 -5
- package/dist/tailwind.cjs +492 -202
- package/dist/tailwind.d.cts +2 -2
- package/dist/tailwind.d.ts +2 -2
- package/dist/tailwind.js +7 -7
- package/dist/{types-C4bz3kDU.d.cts → types-B3SGRW0w.d.cts} +2 -2
- package/dist/{types-VWH6CRvG.d.ts → types-CH7NWqVL.d.ts} +2 -2
- package/dist/ui-tailwind/editor-surface/search-plugin.d.cts +3 -3
- package/dist/ui-tailwind/editor-surface/search-plugin.d.ts +3 -3
- package/dist/ui-tailwind/editor-surface/search-plugin.js +4 -4
- package/dist/ui-tailwind.cjs +492 -202
- package/dist/ui-tailwind.d.cts +3 -3
- package/dist/ui-tailwind.d.ts +3 -3
- package/dist/ui-tailwind.js +7 -7
- package/package.json +1 -1
|
@@ -19,13 +19,13 @@ import {
|
|
|
19
19
|
resolveSectionVariants,
|
|
20
20
|
sectionSupportsStoryTarget,
|
|
21
21
|
storyTargetKey
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-U3UMKA7B.js";
|
|
23
23
|
import {
|
|
24
24
|
createSelectionSnapshot
|
|
25
25
|
} from "./chunk-OYGMRRR7.js";
|
|
26
26
|
import {
|
|
27
27
|
collectCanonicalLayoutInputs
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-RYMMKOFI.js";
|
|
29
29
|
import {
|
|
30
30
|
MAIN_STORY_TARGET,
|
|
31
31
|
createDetachedAnchor,
|
|
@@ -110,6 +110,1175 @@ function createScopeTagRegistry() {
|
|
|
110
110
|
};
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
+
// src/runtime/telemetry/perf-probe.ts
|
|
114
|
+
var PREDICTED_LANE_COUNTERS = {
|
|
115
|
+
applied: "predictions.applied",
|
|
116
|
+
equivalent: "predictions.equivalent",
|
|
117
|
+
adjusted: "predictions.adjusted",
|
|
118
|
+
rejected: "predictions.rejected",
|
|
119
|
+
rollback: "predictions.rollback",
|
|
120
|
+
structuralDivergence: "predictions.structuralDivergence",
|
|
121
|
+
bailBeforePredict: "predictions.bailBeforePredict",
|
|
122
|
+
refreshSelectionOnly: "predictions.refresh.selectionOnly",
|
|
123
|
+
refreshLocalTextEquivalent: "predictions.refresh.localTextEquivalent",
|
|
124
|
+
refreshSurfaceOnly: "predictions.refresh.surfaceOnly",
|
|
125
|
+
refreshFullProjection: "predictions.refresh.fullProjection",
|
|
126
|
+
refreshBlocked: "predictions.refresh.blocked"
|
|
127
|
+
};
|
|
128
|
+
function startPerfProbe(kind) {
|
|
129
|
+
const state = getEnabledState();
|
|
130
|
+
if (!state) {
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
const token = `${kind}-${state.nextToken ?? 0}`;
|
|
134
|
+
state.nextToken = (state.nextToken ?? 0) + 1;
|
|
135
|
+
state.pending ??= {};
|
|
136
|
+
state.pending[token] = {
|
|
137
|
+
kind,
|
|
138
|
+
startedAt: performance.now()
|
|
139
|
+
};
|
|
140
|
+
return token;
|
|
141
|
+
}
|
|
142
|
+
function finishPerfProbe(token) {
|
|
143
|
+
if (!token) {
|
|
144
|
+
return null;
|
|
145
|
+
}
|
|
146
|
+
const state = getEnabledState();
|
|
147
|
+
if (!state?.pending?.[token]) {
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
const pending = state.pending[token];
|
|
151
|
+
delete state.pending[token];
|
|
152
|
+
const sample = {
|
|
153
|
+
token,
|
|
154
|
+
kind: pending.kind,
|
|
155
|
+
durationMs: performance.now() - pending.startedAt,
|
|
156
|
+
recordedAt: Date.now()
|
|
157
|
+
};
|
|
158
|
+
pushSample(state, sample);
|
|
159
|
+
return sample;
|
|
160
|
+
}
|
|
161
|
+
function recordPerfSample(kind, durationMs = 0) {
|
|
162
|
+
const state = getEnabledState();
|
|
163
|
+
if (!state) {
|
|
164
|
+
return null;
|
|
165
|
+
}
|
|
166
|
+
const token = `${kind}-${state.nextToken ?? 0}`;
|
|
167
|
+
state.nextToken = (state.nextToken ?? 0) + 1;
|
|
168
|
+
const sample = {
|
|
169
|
+
token,
|
|
170
|
+
kind,
|
|
171
|
+
durationMs,
|
|
172
|
+
recordedAt: Date.now()
|
|
173
|
+
};
|
|
174
|
+
pushSample(state, sample);
|
|
175
|
+
return sample;
|
|
176
|
+
}
|
|
177
|
+
function incrementInvalidationCounter(counter, amount = 1) {
|
|
178
|
+
const state = getEnabledState();
|
|
179
|
+
if (!state) {
|
|
180
|
+
return 0;
|
|
181
|
+
}
|
|
182
|
+
state.invalidationCounts ??= {};
|
|
183
|
+
state.invalidationCounts[counter] = (state.invalidationCounts[counter] ?? 0) + amount;
|
|
184
|
+
return state.invalidationCounts[counter];
|
|
185
|
+
}
|
|
186
|
+
function getEnabledState() {
|
|
187
|
+
if (typeof window === "undefined") {
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
190
|
+
const state = window.__DOCX_REACT_PERF_PROBE__;
|
|
191
|
+
if (!state?.enabled) {
|
|
192
|
+
return null;
|
|
193
|
+
}
|
|
194
|
+
return state;
|
|
195
|
+
}
|
|
196
|
+
function pushSample(state, sample) {
|
|
197
|
+
state.samples ??= [];
|
|
198
|
+
state.samples.push(sample);
|
|
199
|
+
const maxSamples = state.maxSamples ?? 20;
|
|
200
|
+
if (state.samples.length > maxSamples) {
|
|
201
|
+
state.samples.splice(0, state.samples.length - maxSamples);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// src/runtime/render/decoration-resolver.ts
|
|
206
|
+
function resolveDecorationIndex(input) {
|
|
207
|
+
const workflow = [];
|
|
208
|
+
const comments = [];
|
|
209
|
+
const revisions = [];
|
|
210
|
+
const search = [];
|
|
211
|
+
const locked = [];
|
|
212
|
+
if (input.workflowSegments) {
|
|
213
|
+
for (const segment of input.workflowSegments) {
|
|
214
|
+
const frame = input.anchorIndex.bySelection(
|
|
215
|
+
segment.fromOffset,
|
|
216
|
+
segment.toOffset
|
|
217
|
+
);
|
|
218
|
+
if (!frame) continue;
|
|
219
|
+
workflow.push({
|
|
220
|
+
kind: "workflow",
|
|
221
|
+
refId: segment.scopeId,
|
|
222
|
+
frame
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
if (input.comments) {
|
|
227
|
+
for (const thread of input.comments.threads) {
|
|
228
|
+
const frame = resolveRange(
|
|
229
|
+
input.anchorIndex,
|
|
230
|
+
thread.from,
|
|
231
|
+
thread.to
|
|
232
|
+
);
|
|
233
|
+
if (!frame) continue;
|
|
234
|
+
comments.push({
|
|
235
|
+
kind: "comment",
|
|
236
|
+
refId: thread.commentId,
|
|
237
|
+
frame
|
|
238
|
+
});
|
|
239
|
+
void asCommentThread(thread);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
if (input.revisions) {
|
|
243
|
+
for (const revision of input.revisions.revisions) {
|
|
244
|
+
const frame = resolveRange(
|
|
245
|
+
input.anchorIndex,
|
|
246
|
+
revision.from,
|
|
247
|
+
revision.to
|
|
248
|
+
);
|
|
249
|
+
if (!frame) continue;
|
|
250
|
+
revisions.push({
|
|
251
|
+
kind: "revision",
|
|
252
|
+
refId: revision.revisionId,
|
|
253
|
+
frame
|
|
254
|
+
});
|
|
255
|
+
void asRevisionEntry(revision);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
if (input.searchMatches) {
|
|
259
|
+
for (const match of input.searchMatches) {
|
|
260
|
+
const frame = resolveRange(input.anchorIndex, match.from, match.to);
|
|
261
|
+
if (!frame) continue;
|
|
262
|
+
search.push({
|
|
263
|
+
kind: "search",
|
|
264
|
+
refId: match.matchId,
|
|
265
|
+
frame
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
if (input.lockedRanges) {
|
|
270
|
+
for (const lock of input.lockedRanges) {
|
|
271
|
+
const frame = resolveRange(input.anchorIndex, lock.from, lock.to);
|
|
272
|
+
if (!frame) continue;
|
|
273
|
+
locked.push({
|
|
274
|
+
kind: "locked",
|
|
275
|
+
refId: lock.lockId,
|
|
276
|
+
frame
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
return { workflow, comments, revisions, search, locked };
|
|
281
|
+
}
|
|
282
|
+
function resolveRange(anchorIndex, from, to) {
|
|
283
|
+
if (from >= to) {
|
|
284
|
+
return anchorIndex.byRuntimeOffset(from);
|
|
285
|
+
}
|
|
286
|
+
return anchorIndex.bySelection(from, to);
|
|
287
|
+
}
|
|
288
|
+
function asCommentThread(thread) {
|
|
289
|
+
return thread;
|
|
290
|
+
}
|
|
291
|
+
function asRevisionEntry(entry) {
|
|
292
|
+
return entry;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// src/runtime/render/block-fragment-projection.ts
|
|
296
|
+
function classifyBlockKind(blockId) {
|
|
297
|
+
if (blockId.startsWith("paragraph")) return "paragraph";
|
|
298
|
+
if (blockId.startsWith("table")) return "table";
|
|
299
|
+
if (blockId.startsWith("placeholder-culled-")) return "opaque";
|
|
300
|
+
if (blockId.startsWith("opaque")) return "opaque";
|
|
301
|
+
if (blockId.startsWith("section-break")) return "opaque";
|
|
302
|
+
if (blockId.startsWith("sdt")) return "opaque";
|
|
303
|
+
if (blockId.startsWith("custom-xml")) return "opaque";
|
|
304
|
+
if (blockId.startsWith("alt-chunk")) return "opaque";
|
|
305
|
+
if (blockId.startsWith("synthetic")) return "synthetic";
|
|
306
|
+
return "paragraph";
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// src/runtime/render/render-frame-diff.ts
|
|
310
|
+
function diffRenderFrames(prev, next) {
|
|
311
|
+
if (!prev) {
|
|
312
|
+
return {
|
|
313
|
+
addedPages: next.pages.map((p) => p.page.pageIndex),
|
|
314
|
+
removedPages: [],
|
|
315
|
+
unchangedPages: [],
|
|
316
|
+
changedPages: []
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
const prevByIndex = /* @__PURE__ */ new Map();
|
|
320
|
+
for (const page of prev.pages) {
|
|
321
|
+
prevByIndex.set(page.page.pageIndex, page);
|
|
322
|
+
}
|
|
323
|
+
const nextIndices = /* @__PURE__ */ new Set();
|
|
324
|
+
for (const page of next.pages) {
|
|
325
|
+
nextIndices.add(page.page.pageIndex);
|
|
326
|
+
}
|
|
327
|
+
const addedPages = [];
|
|
328
|
+
const removedPages = [];
|
|
329
|
+
const unchangedPages = [];
|
|
330
|
+
const changedPages = [];
|
|
331
|
+
for (const nextPage of next.pages) {
|
|
332
|
+
const pageIndex = nextPage.page.pageIndex;
|
|
333
|
+
const prevPage = prevByIndex.get(pageIndex);
|
|
334
|
+
if (!prevPage) {
|
|
335
|
+
addedPages.push(pageIndex);
|
|
336
|
+
continue;
|
|
337
|
+
}
|
|
338
|
+
const regions = diffPage(prevPage, nextPage, prev.decorationIndex, next.decorationIndex);
|
|
339
|
+
const frameChanged = !rectEquals(prevPage.frame, nextPage.frame);
|
|
340
|
+
const reservationsChanged = !reservationsEqual(
|
|
341
|
+
prevPage.chromeReservations,
|
|
342
|
+
nextPage.chromeReservations
|
|
343
|
+
);
|
|
344
|
+
if (regions.length === 0 && !frameChanged && !reservationsChanged) {
|
|
345
|
+
unchangedPages.push(pageIndex);
|
|
346
|
+
} else {
|
|
347
|
+
changedPages.push({
|
|
348
|
+
pageIndex,
|
|
349
|
+
regions,
|
|
350
|
+
...frameChanged ? { pageFrameChanged: true } : {}
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
for (const prevPage of prev.pages) {
|
|
355
|
+
if (!nextIndices.has(prevPage.page.pageIndex)) {
|
|
356
|
+
removedPages.push(prevPage.page.pageIndex);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
return { addedPages, removedPages, unchangedPages, changedPages };
|
|
360
|
+
}
|
|
361
|
+
function createPagePatchPlan(prev, next, diff = diffRenderFrames(prev, next), options = {}) {
|
|
362
|
+
const prevByIndex = indexPagesByIndex(prev?.pages ?? []);
|
|
363
|
+
const nextByIndex = indexPagesByIndex(next.pages);
|
|
364
|
+
const addedPages = diff.addedPages.map(
|
|
365
|
+
(pageIndex) => pageIdForIndex(nextByIndex, pageIndex)
|
|
366
|
+
);
|
|
367
|
+
const removedPages = diff.removedPages.map(
|
|
368
|
+
(pageIndex) => pageIdForIndex(prevByIndex, pageIndex)
|
|
369
|
+
);
|
|
370
|
+
const unchangedPages = diff.unchangedPages.map(
|
|
371
|
+
(pageIndex) => pageIdForIndex(nextByIndex, pageIndex)
|
|
372
|
+
);
|
|
373
|
+
const changedPages = diff.changedPages.map(
|
|
374
|
+
(entry) => createPagePatchEntry(entry, pageIdForIndex(nextByIndex, entry.pageIndex), options)
|
|
375
|
+
);
|
|
376
|
+
return {
|
|
377
|
+
layoutRevision: options.layoutRevision ?? next.revision,
|
|
378
|
+
geometryRevision: options.geometryRevision ?? next.revision,
|
|
379
|
+
addedPages,
|
|
380
|
+
removedPages,
|
|
381
|
+
unchangedPages,
|
|
382
|
+
changedPages,
|
|
383
|
+
mountChanges: resolveMountChanges({
|
|
384
|
+
addedPages,
|
|
385
|
+
removedPages,
|
|
386
|
+
mountedPageIds: options.mountedPageIds,
|
|
387
|
+
requestedMountPageIds: options.requestedMountPageIds
|
|
388
|
+
})
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
function createPagePatchEntry(entry, pageId, options) {
|
|
392
|
+
const regionChanges = entry.regions.map((region) => region.kind);
|
|
393
|
+
const fragmentChanges = uniqueStrings(
|
|
394
|
+
entry.regions.flatMap((region) => region.changedBlockIds)
|
|
395
|
+
);
|
|
396
|
+
const overlayLaneChanges = !entry.pageFrameChanged && entry.regions.length === 0 ? ["chrome-reservations"] : [];
|
|
397
|
+
return {
|
|
398
|
+
pageId,
|
|
399
|
+
pageIndex: entry.pageIndex,
|
|
400
|
+
frameChanged: entry.pageFrameChanged === true,
|
|
401
|
+
regionChanges,
|
|
402
|
+
fragmentChanges,
|
|
403
|
+
lineBoxChanges: fragmentChanges,
|
|
404
|
+
overlayLaneChanges,
|
|
405
|
+
reason: options.reason ?? (overlayLaneChanges.length > 0 ? "overlay" : "layout")
|
|
406
|
+
};
|
|
407
|
+
}
|
|
408
|
+
function resolveMountChanges(input) {
|
|
409
|
+
if (!input.mountedPageIds || !input.requestedMountPageIds) {
|
|
410
|
+
return {
|
|
411
|
+
mountPageIds: input.addedPages,
|
|
412
|
+
unmountPageIds: input.removedPages
|
|
413
|
+
};
|
|
414
|
+
}
|
|
415
|
+
const mounted = new Set(input.mountedPageIds);
|
|
416
|
+
const requested = new Set(input.requestedMountPageIds);
|
|
417
|
+
return {
|
|
418
|
+
mountPageIds: input.requestedMountPageIds.filter((pageId) => !mounted.has(pageId)),
|
|
419
|
+
unmountPageIds: input.mountedPageIds.filter((pageId) => !requested.has(pageId))
|
|
420
|
+
};
|
|
421
|
+
}
|
|
422
|
+
function indexPagesByIndex(pages) {
|
|
423
|
+
return new Map(pages.map((page) => [page.page.pageIndex, page]));
|
|
424
|
+
}
|
|
425
|
+
function pageIdForIndex(pages, pageIndex) {
|
|
426
|
+
return pages.get(pageIndex)?.page.pageId ?? `page:${pageIndex}`;
|
|
427
|
+
}
|
|
428
|
+
function uniqueStrings(values) {
|
|
429
|
+
return [...new Set(values)];
|
|
430
|
+
}
|
|
431
|
+
function diffPage(prev, next, prevIndex, nextIndex) {
|
|
432
|
+
const changed = [];
|
|
433
|
+
const bodyChanges = diffRegion(prev.regions.body, next.regions.body, prevIndex, nextIndex);
|
|
434
|
+
if (bodyChanges.length > 0) {
|
|
435
|
+
changed.push({ kind: "body", changedBlockIds: bodyChanges });
|
|
436
|
+
}
|
|
437
|
+
const headerChanges = diffOptionalRegion(
|
|
438
|
+
prev.regions.header,
|
|
439
|
+
next.regions.header,
|
|
440
|
+
prevIndex,
|
|
441
|
+
nextIndex
|
|
442
|
+
);
|
|
443
|
+
if (headerChanges.length > 0) {
|
|
444
|
+
changed.push({ kind: "header", changedBlockIds: headerChanges });
|
|
445
|
+
}
|
|
446
|
+
const footerChanges = diffOptionalRegion(
|
|
447
|
+
prev.regions.footer,
|
|
448
|
+
next.regions.footer,
|
|
449
|
+
prevIndex,
|
|
450
|
+
nextIndex
|
|
451
|
+
);
|
|
452
|
+
if (footerChanges.length > 0) {
|
|
453
|
+
changed.push({ kind: "footer", changedBlockIds: footerChanges });
|
|
454
|
+
}
|
|
455
|
+
const prevFoot = prev.regions.footnotes ?? [];
|
|
456
|
+
const nextFoot = next.regions.footnotes ?? [];
|
|
457
|
+
if (prevFoot.length !== nextFoot.length) {
|
|
458
|
+
changed.push({ kind: "footnote-area", changedBlockIds: ["<count-changed>"] });
|
|
459
|
+
} else {
|
|
460
|
+
for (let i = 0; i < prevFoot.length; i += 1) {
|
|
461
|
+
const fChanges = diffRegion(prevFoot[i], nextFoot[i], prevIndex, nextIndex);
|
|
462
|
+
if (fChanges.length > 0) {
|
|
463
|
+
changed.push({ kind: "footnote-area", changedBlockIds: fChanges });
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
return changed;
|
|
468
|
+
}
|
|
469
|
+
function diffOptionalRegion(prev, next, prevIndex, nextIndex) {
|
|
470
|
+
if (!prev && !next) return [];
|
|
471
|
+
if (!prev && next) return ["<added>"];
|
|
472
|
+
if (prev && !next) return ["<removed>"];
|
|
473
|
+
return diffRegion(prev, next, prevIndex, nextIndex);
|
|
474
|
+
}
|
|
475
|
+
function diffRegion(prev, next, prevIndex, nextIndex) {
|
|
476
|
+
const changed = [];
|
|
477
|
+
if (!rectEquals(prev.frame, next.frame)) {
|
|
478
|
+
changed.push("<region-frame>");
|
|
479
|
+
}
|
|
480
|
+
const prevBlocks = /* @__PURE__ */ new Map();
|
|
481
|
+
for (const block of prev.blocks) {
|
|
482
|
+
prevBlocks.set(block.fragment.blockId, block);
|
|
483
|
+
}
|
|
484
|
+
const nextIds = /* @__PURE__ */ new Set();
|
|
485
|
+
for (const block of next.blocks) {
|
|
486
|
+
nextIds.add(block.fragment.blockId);
|
|
487
|
+
const prevBlock = prevBlocks.get(block.fragment.blockId);
|
|
488
|
+
if (!prevBlock) {
|
|
489
|
+
changed.push(block.fragment.blockId);
|
|
490
|
+
continue;
|
|
491
|
+
}
|
|
492
|
+
if (!blocksStructurallyEqual(prevBlock, block, prevIndex, nextIndex)) {
|
|
493
|
+
changed.push(block.fragment.blockId);
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
for (const blockId of prevBlocks.keys()) {
|
|
497
|
+
if (!nextIds.has(blockId)) changed.push(blockId);
|
|
498
|
+
}
|
|
499
|
+
return changed;
|
|
500
|
+
}
|
|
501
|
+
function blocksStructurallyEqual(a, b, aIndex, bIndex) {
|
|
502
|
+
if (a.kind !== b.kind) return false;
|
|
503
|
+
if (a.fragment.regionKind !== b.fragment.regionKind) return false;
|
|
504
|
+
if (a.fragment.from !== b.fragment.from) return false;
|
|
505
|
+
if (a.fragment.to !== b.fragment.to) return false;
|
|
506
|
+
if (!rectEquals(a.frame, b.frame)) return false;
|
|
507
|
+
if (a.lines.length !== b.lines.length) return false;
|
|
508
|
+
for (let i = 0; i < a.lines.length; i += 1) {
|
|
509
|
+
if (!rectEquals(a.lines[i].frame, b.lines[i].frame)) return false;
|
|
510
|
+
}
|
|
511
|
+
const aHash = decorationHashForBlock(a.frame, aIndex);
|
|
512
|
+
const bHash = decorationHashForBlock(b.frame, bIndex);
|
|
513
|
+
if (aHash !== bHash) return false;
|
|
514
|
+
return true;
|
|
515
|
+
}
|
|
516
|
+
function decorationHashForBlock(blockFrame, index) {
|
|
517
|
+
const tokens = [];
|
|
518
|
+
for (const lane of [index.workflow, index.comments, index.revisions, index.search, index.locked]) {
|
|
519
|
+
for (const entry of lane) {
|
|
520
|
+
if (rectIntersects(entry.frame, blockFrame)) {
|
|
521
|
+
tokens.push(`${entry.kind}:${entry.refId}`);
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
tokens.sort();
|
|
526
|
+
return tokens.join("|");
|
|
527
|
+
}
|
|
528
|
+
function reservationsEqual(a, b) {
|
|
529
|
+
return a.railLaneTwips === b.railLaneTwips && a.balloonLaneTwips === b.balloonLaneTwips && a.footnoteAreaTwips === b.footnoteAreaTwips && a.pageFrameWidthPx === b.pageFrameWidthPx && a.pageFrameHeightPx === b.pageFrameHeightPx;
|
|
530
|
+
}
|
|
531
|
+
var RECT_EPS = 0.1;
|
|
532
|
+
function rectEquals(a, b) {
|
|
533
|
+
return Math.abs(a.leftPx - b.leftPx) < RECT_EPS && Math.abs(a.topPx - b.topPx) < RECT_EPS && Math.abs(a.widthPx - b.widthPx) < RECT_EPS && Math.abs(a.heightPx - b.heightPx) < RECT_EPS;
|
|
534
|
+
}
|
|
535
|
+
function rectIntersects(a, b) {
|
|
536
|
+
return !(a.leftPx + a.widthPx <= b.leftPx || b.leftPx + b.widthPx <= a.leftPx || a.topPx + a.heightPx <= b.topPx || b.topPx + b.heightPx <= a.topPx);
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
// src/runtime/render/render-frame-types.ts
|
|
540
|
+
var DEFAULT_PX_PER_TWIP = 96 / 1440;
|
|
541
|
+
var PAGE_STACK_GAP_PX = 48;
|
|
542
|
+
function resolveDefaultZoom(input = {}) {
|
|
543
|
+
return {
|
|
544
|
+
pxPerTwip: input.pxPerTwip ?? DEFAULT_PX_PER_TWIP,
|
|
545
|
+
viewportWidthPx: input.viewportWidthPx ?? 900,
|
|
546
|
+
fitMode: input.fitMode ?? "fixed"
|
|
547
|
+
};
|
|
548
|
+
}
|
|
549
|
+
var EMPTY_DECORATION_INDEX = Object.freeze({
|
|
550
|
+
workflow: Object.freeze([]),
|
|
551
|
+
comments: Object.freeze([]),
|
|
552
|
+
revisions: Object.freeze([]),
|
|
553
|
+
search: Object.freeze([]),
|
|
554
|
+
locked: Object.freeze([])
|
|
555
|
+
});
|
|
556
|
+
function defaultChromeReservations(layout, zoom) {
|
|
557
|
+
return {
|
|
558
|
+
railLaneTwips: 360,
|
|
559
|
+
balloonLaneTwips: 2160,
|
|
560
|
+
footnoteAreaTwips: 0,
|
|
561
|
+
pageFrameWidthPx: layout.pageWidth * zoom.pxPerTwip,
|
|
562
|
+
pageFrameHeightPx: layout.pageHeight * zoom.pxPerTwip
|
|
563
|
+
};
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
// src/runtime/render/render-kernel.ts
|
|
567
|
+
function sumDeltasBefore(deltas, runtimeOffset) {
|
|
568
|
+
let total = 0;
|
|
569
|
+
for (const d of deltas) {
|
|
570
|
+
if (d.fromRuntime <= runtimeOffset) total += d.delta;
|
|
571
|
+
}
|
|
572
|
+
return total;
|
|
573
|
+
}
|
|
574
|
+
function createRenderKernel(input) {
|
|
575
|
+
const { facet } = input;
|
|
576
|
+
const getActiveStory = input.getActiveStory ?? (() => MAIN_STORY_TARGET);
|
|
577
|
+
let zoom = input.initialZoom ?? resolveDefaultZoom();
|
|
578
|
+
let cache = null;
|
|
579
|
+
let lastEmittedFrame = null;
|
|
580
|
+
let diCacheKey = null;
|
|
581
|
+
let diCacheValue = null;
|
|
582
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
583
|
+
const unsubscribeFacet = facet.subscribe((event) => {
|
|
584
|
+
if (event.kind === "layout_recomputed" || event.kind === "incremental_relayout" || event.kind === "measurement_backend_ready" || event.kind === "zoom_changed") {
|
|
585
|
+
cache = null;
|
|
586
|
+
}
|
|
587
|
+
});
|
|
588
|
+
void unsubscribeFacet;
|
|
589
|
+
function emit(event) {
|
|
590
|
+
for (const listener of listeners) {
|
|
591
|
+
try {
|
|
592
|
+
listener(event);
|
|
593
|
+
} catch {
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
function buildFrame(options) {
|
|
598
|
+
const t0 = typeof performance !== "undefined" ? performance.now() : 0;
|
|
599
|
+
const activeStory = options?.story ?? getActiveStory();
|
|
600
|
+
const measurementFidelity = facet.getMeasurementFidelity();
|
|
601
|
+
const rawPages = facet.getPages();
|
|
602
|
+
const pageRange = options?.pageRange;
|
|
603
|
+
const filteredPages = pageRange ? rawPages.filter(
|
|
604
|
+
(p) => p.pageIndex >= pageRange.fromPageIndex && p.pageIndex <= pageRange.toPageIndex
|
|
605
|
+
) : rawPages;
|
|
606
|
+
let y = 0;
|
|
607
|
+
const renderPages = [];
|
|
608
|
+
for (const page of filteredPages) {
|
|
609
|
+
const renderPage = buildPage(page, y, zoom, activeStory, facet);
|
|
610
|
+
renderPages.push(renderPage);
|
|
611
|
+
y += renderPage.frame.heightPx + PAGE_STACK_GAP_PX;
|
|
612
|
+
}
|
|
613
|
+
const pendingDeltas = input.getPendingOpDeltas?.() ?? [];
|
|
614
|
+
const baseAnchorIndex = buildAnchorIndex(
|
|
615
|
+
renderPages,
|
|
616
|
+
pendingDeltas,
|
|
617
|
+
zoom.pxPerTwip
|
|
618
|
+
);
|
|
619
|
+
const revision = filteredPages[0] ? Number(extractRevisionFromPageId(filteredPages[0].pageId)) : 0;
|
|
620
|
+
const includeDecorations = options?.includeDecorations ?? true;
|
|
621
|
+
const sources = input.getDecorationSources?.();
|
|
622
|
+
const hasSources = sources !== void 0 && (sources.workflowSegments && sources.workflowSegments.length > 0 || (sources.comments?.threads?.length ?? 0) > 0 || (sources.revisions?.revisions?.length ?? 0) > 0 || sources.searchMatches && sources.searchMatches.length > 0 || sources.lockedRanges && sources.lockedRanges.length > 0);
|
|
623
|
+
const newDIKey = {
|
|
624
|
+
revision: Number.isFinite(revision) ? revision : 0,
|
|
625
|
+
activeStoryKind: activeStory.kind,
|
|
626
|
+
zoomPxPerTwip: zoom.pxPerTwip,
|
|
627
|
+
workflowSegments: sources?.workflowSegments,
|
|
628
|
+
comments: sources?.comments,
|
|
629
|
+
revisions: sources?.revisions,
|
|
630
|
+
searchMatches: sources?.searchMatches,
|
|
631
|
+
lockedRanges: sources?.lockedRanges
|
|
632
|
+
};
|
|
633
|
+
const diCacheHit = hasSources && diCacheKey !== null && diCacheValue !== null && diCacheKey.revision === newDIKey.revision && diCacheKey.activeStoryKind === newDIKey.activeStoryKind && diCacheKey.zoomPxPerTwip === newDIKey.zoomPxPerTwip && diCacheKey.workflowSegments === newDIKey.workflowSegments && diCacheKey.comments === newDIKey.comments && diCacheKey.revisions === newDIKey.revisions && diCacheKey.searchMatches === newDIKey.searchMatches && diCacheKey.lockedRanges === newDIKey.lockedRanges;
|
|
634
|
+
let decorationIndex;
|
|
635
|
+
if (!includeDecorations) {
|
|
636
|
+
decorationIndex = EMPTY_DECORATION_INDEX;
|
|
637
|
+
} else if (hasSources) {
|
|
638
|
+
if (diCacheHit) {
|
|
639
|
+
decorationIndex = diCacheValue;
|
|
640
|
+
} else {
|
|
641
|
+
decorationIndex = resolveDecorationIndex({ anchorIndex: baseAnchorIndex, ...sources });
|
|
642
|
+
diCacheKey = newDIKey;
|
|
643
|
+
diCacheValue = decorationIndex;
|
|
644
|
+
}
|
|
645
|
+
} else {
|
|
646
|
+
decorationIndex = buildDecorationIndex(renderPages);
|
|
647
|
+
}
|
|
648
|
+
const anchorIndex = buildAnchorIndex(
|
|
649
|
+
renderPages,
|
|
650
|
+
pendingDeltas,
|
|
651
|
+
zoom.pxPerTwip,
|
|
652
|
+
decorationIndex
|
|
653
|
+
);
|
|
654
|
+
const frame = {
|
|
655
|
+
revision: Number.isFinite(revision) ? revision : 0,
|
|
656
|
+
measurementFidelity,
|
|
657
|
+
activeStory,
|
|
658
|
+
zoom: { ...zoom },
|
|
659
|
+
pages: renderPages,
|
|
660
|
+
decorationIndex,
|
|
661
|
+
anchorIndex
|
|
662
|
+
};
|
|
663
|
+
if (t0 > 0) recordPerfSample("render.frame_build", performance.now() - t0);
|
|
664
|
+
return frame;
|
|
665
|
+
}
|
|
666
|
+
return {
|
|
667
|
+
getRenderFrame(options) {
|
|
668
|
+
const rebuild = options !== void 0 || cache === null;
|
|
669
|
+
if (!rebuild && cache) {
|
|
670
|
+
return cache.frame;
|
|
671
|
+
}
|
|
672
|
+
const frame = buildFrame(options);
|
|
673
|
+
if (options === void 0) {
|
|
674
|
+
cache = { revision: frame.revision, frame };
|
|
675
|
+
emit({ kind: "frame_built", revision: frame.revision, reason: "full" });
|
|
676
|
+
const diffT0 = typeof performance !== "undefined" ? performance.now() : 0;
|
|
677
|
+
const diff = diffRenderFrames(lastEmittedFrame, frame);
|
|
678
|
+
const patchPlan = createPagePatchPlan(lastEmittedFrame, frame, diff);
|
|
679
|
+
recordPagePatchPlanTelemetry(patchPlan);
|
|
680
|
+
if (diffT0 > 0) {
|
|
681
|
+
recordPerfSample("render.frame_diff", performance.now() - diffT0);
|
|
682
|
+
}
|
|
683
|
+
emit({ kind: "frame_diff", revision: frame.revision, diff, patchPlan });
|
|
684
|
+
lastEmittedFrame = frame;
|
|
685
|
+
}
|
|
686
|
+
return frame;
|
|
687
|
+
},
|
|
688
|
+
getZoom() {
|
|
689
|
+
return { ...zoom };
|
|
690
|
+
},
|
|
691
|
+
setZoom(next) {
|
|
692
|
+
zoom = { ...next };
|
|
693
|
+
cache = null;
|
|
694
|
+
},
|
|
695
|
+
subscribe(listener) {
|
|
696
|
+
listeners.add(listener);
|
|
697
|
+
return () => {
|
|
698
|
+
listeners.delete(listener);
|
|
699
|
+
};
|
|
700
|
+
},
|
|
701
|
+
invalidate() {
|
|
702
|
+
cache = null;
|
|
703
|
+
}
|
|
704
|
+
};
|
|
705
|
+
}
|
|
706
|
+
function recordPagePatchPlanTelemetry(plan) {
|
|
707
|
+
incrementInvalidationCounter(
|
|
708
|
+
"pageRender.patch.addedPages",
|
|
709
|
+
plan.addedPages.length
|
|
710
|
+
);
|
|
711
|
+
incrementInvalidationCounter(
|
|
712
|
+
"pageRender.patch.removedPages",
|
|
713
|
+
plan.removedPages.length
|
|
714
|
+
);
|
|
715
|
+
incrementInvalidationCounter(
|
|
716
|
+
"pageRender.patch.unchangedPages",
|
|
717
|
+
plan.unchangedPages.length
|
|
718
|
+
);
|
|
719
|
+
incrementInvalidationCounter(
|
|
720
|
+
"pageRender.patch.changedFragments",
|
|
721
|
+
plan.changedPages.reduce(
|
|
722
|
+
(total, page) => total + page.fragmentChanges.length,
|
|
723
|
+
0
|
|
724
|
+
)
|
|
725
|
+
);
|
|
726
|
+
incrementInvalidationCounter(
|
|
727
|
+
"pageRender.patch.mountedPages",
|
|
728
|
+
plan.mountChanges.mountPageIds.length
|
|
729
|
+
);
|
|
730
|
+
incrementInvalidationCounter(
|
|
731
|
+
"pageRender.patch.unmountedPages",
|
|
732
|
+
plan.mountChanges.unmountPageIds.length
|
|
733
|
+
);
|
|
734
|
+
}
|
|
735
|
+
function buildPage(page, topPx, zoom, activeStory, facet) {
|
|
736
|
+
const layout = page.layout;
|
|
737
|
+
const widthPx = layout.pageWidth * zoom.pxPerTwip;
|
|
738
|
+
const heightPx = layout.pageHeight * zoom.pxPerTwip;
|
|
739
|
+
const frame = {
|
|
740
|
+
leftPx: 0,
|
|
741
|
+
topPx,
|
|
742
|
+
widthPx,
|
|
743
|
+
heightPx
|
|
744
|
+
};
|
|
745
|
+
const bodyRegion = buildBodyRegion(
|
|
746
|
+
page,
|
|
747
|
+
topPx,
|
|
748
|
+
zoom,
|
|
749
|
+
activeStory,
|
|
750
|
+
facet
|
|
751
|
+
);
|
|
752
|
+
const regions = {
|
|
753
|
+
body: bodyRegion
|
|
754
|
+
};
|
|
755
|
+
if (page.stories.header) {
|
|
756
|
+
regions.header = buildHeaderFooterRegion(
|
|
757
|
+
page,
|
|
758
|
+
topPx,
|
|
759
|
+
zoom,
|
|
760
|
+
"header",
|
|
761
|
+
page.stories.header,
|
|
762
|
+
facet
|
|
763
|
+
);
|
|
764
|
+
}
|
|
765
|
+
if (page.stories.footer) {
|
|
766
|
+
regions.footer = buildHeaderFooterRegion(
|
|
767
|
+
page,
|
|
768
|
+
topPx,
|
|
769
|
+
zoom,
|
|
770
|
+
"footer",
|
|
771
|
+
page.stories.footer,
|
|
772
|
+
facet
|
|
773
|
+
);
|
|
774
|
+
}
|
|
775
|
+
const footnoteRegions = buildFootnoteRegions(page, topPx, zoom, facet);
|
|
776
|
+
if (footnoteRegions.length > 0) {
|
|
777
|
+
regions.footnotes = footnoteRegions;
|
|
778
|
+
}
|
|
779
|
+
const chromeReservations = {
|
|
780
|
+
...defaultChromeReservations(layout, zoom)
|
|
781
|
+
};
|
|
782
|
+
return {
|
|
783
|
+
page,
|
|
784
|
+
frame,
|
|
785
|
+
regions,
|
|
786
|
+
chromeReservations
|
|
787
|
+
};
|
|
788
|
+
}
|
|
789
|
+
function buildBodyRegion(page, pageTopPx, zoom, activeStory, facet) {
|
|
790
|
+
const layout = page.layout;
|
|
791
|
+
const bodyLeftTwips = layout.marginLeft;
|
|
792
|
+
const bodyTopTwips = layout.marginTop;
|
|
793
|
+
const bodyWidthTwips = page.regions.body.widthTwips;
|
|
794
|
+
const bodyHeightTwips = page.regions.body.heightTwips;
|
|
795
|
+
const regionFrame = {
|
|
796
|
+
leftPx: bodyLeftTwips * zoom.pxPerTwip,
|
|
797
|
+
topPx: pageTopPx + bodyTopTwips * zoom.pxPerTwip,
|
|
798
|
+
widthPx: bodyWidthTwips * zoom.pxPerTwip,
|
|
799
|
+
heightPx: bodyHeightTwips * zoom.pxPerTwip
|
|
800
|
+
};
|
|
801
|
+
const fragments = facet.getFragmentsForPage(page.pageIndex);
|
|
802
|
+
const bodyLineBoxes = facet.getLineBoxes(page.pageIndex, { region: "body" });
|
|
803
|
+
const blocks = [];
|
|
804
|
+
let blockY = regionFrame.topPx;
|
|
805
|
+
const totalFragmentHeight = fragments.reduce(
|
|
806
|
+
(acc, fragment) => acc + Math.max(0, fragment.heightTwips),
|
|
807
|
+
0
|
|
808
|
+
);
|
|
809
|
+
for (const fragment of fragments) {
|
|
810
|
+
if (fragment.regionKind !== "body") continue;
|
|
811
|
+
const fragmentHeightTwips = fragment.heightTwips > 0 ? fragment.heightTwips : totalFragmentHeight === 0 ? bodyHeightTwips / Math.max(1, fragments.length) : 0;
|
|
812
|
+
const blockHeightPx = fragmentHeightTwips * zoom.pxPerTwip;
|
|
813
|
+
const fallbackBlockFrame = {
|
|
814
|
+
leftPx: regionFrame.leftPx,
|
|
815
|
+
topPx: blockY,
|
|
816
|
+
widthPx: regionFrame.widthPx,
|
|
817
|
+
heightPx: blockHeightPx
|
|
818
|
+
};
|
|
819
|
+
const blockLines = bodyLineBoxes.filter((box) => box.fragmentId === fragment.fragmentId).map((box) => {
|
|
820
|
+
const lineFrame = lineFrameFromPublicBox(
|
|
821
|
+
box,
|
|
822
|
+
regionFrame,
|
|
823
|
+
pageTopPx,
|
|
824
|
+
bodyTopTwips,
|
|
825
|
+
zoom
|
|
826
|
+
);
|
|
827
|
+
const anchors = [
|
|
828
|
+
{
|
|
829
|
+
runtimeOffset: fragment.from,
|
|
830
|
+
frame: lineFrame,
|
|
831
|
+
fragmentId: fragment.fragmentId,
|
|
832
|
+
blockId: fragment.blockId
|
|
833
|
+
}
|
|
834
|
+
];
|
|
835
|
+
return {
|
|
836
|
+
line: box,
|
|
837
|
+
frame: lineFrame,
|
|
838
|
+
anchors
|
|
839
|
+
};
|
|
840
|
+
});
|
|
841
|
+
const kind = classifyBlockKind(fragment.blockId);
|
|
842
|
+
const blockFrame = blockFrameFromLineFacts(
|
|
843
|
+
fallbackBlockFrame,
|
|
844
|
+
kind,
|
|
845
|
+
blockLines
|
|
846
|
+
);
|
|
847
|
+
const tablePlan = kind === "table" ? facet.getTableRenderPlan(fragment.blockId, page.pageIndex) : void 0;
|
|
848
|
+
blocks.push({
|
|
849
|
+
fragment,
|
|
850
|
+
frame: blockFrame,
|
|
851
|
+
kind,
|
|
852
|
+
lines: blockLines,
|
|
853
|
+
blockDecorations: [],
|
|
854
|
+
...tablePlan !== void 0 ? { tablePlan } : {}
|
|
855
|
+
});
|
|
856
|
+
blockY = Math.max(blockY + blockHeightPx, blockFrame.topPx + blockFrame.heightPx);
|
|
857
|
+
}
|
|
858
|
+
return {
|
|
859
|
+
storyTarget: activeStory,
|
|
860
|
+
region: page.regions.body,
|
|
861
|
+
frame: regionFrame,
|
|
862
|
+
blocks
|
|
863
|
+
};
|
|
864
|
+
}
|
|
865
|
+
function lineFrameFromPublicBox(box, regionFrame, pageTopPx, bodyTopTwips, zoom) {
|
|
866
|
+
if (box.rectTwips) {
|
|
867
|
+
return projectPageTwipsRectToFrame(box.rectTwips, pageTopPx, zoom);
|
|
868
|
+
}
|
|
869
|
+
const lineTopPx = pageTopPx + (bodyTopTwips + box.baselineTwips) * zoom.pxPerTwip;
|
|
870
|
+
return {
|
|
871
|
+
leftPx: regionFrame.leftPx,
|
|
872
|
+
topPx: lineTopPx,
|
|
873
|
+
widthPx: Math.min(
|
|
874
|
+
regionFrame.widthPx,
|
|
875
|
+
box.widthTwips * zoom.pxPerTwip
|
|
876
|
+
),
|
|
877
|
+
heightPx: box.heightTwips * zoom.pxPerTwip
|
|
878
|
+
};
|
|
879
|
+
}
|
|
880
|
+
function projectPageTwipsRectToFrame(rect2, pageTopPx, zoom) {
|
|
881
|
+
return {
|
|
882
|
+
leftPx: rect2.xTwips * zoom.pxPerTwip,
|
|
883
|
+
topPx: pageTopPx + rect2.yTwips * zoom.pxPerTwip,
|
|
884
|
+
widthPx: rect2.widthTwips * zoom.pxPerTwip,
|
|
885
|
+
heightPx: rect2.heightTwips * zoom.pxPerTwip
|
|
886
|
+
};
|
|
887
|
+
}
|
|
888
|
+
function blockFrameFromLineFacts(fallback, kind, lines) {
|
|
889
|
+
const union = unionRenderLineFrames(lines);
|
|
890
|
+
if (!union) return fallback;
|
|
891
|
+
if (kind === "paragraph") return union;
|
|
892
|
+
if (fallback.widthPx <= 0 || fallback.heightPx <= 0) return union;
|
|
893
|
+
return fallback;
|
|
894
|
+
}
|
|
895
|
+
function unionRenderLineFrames(lines) {
|
|
896
|
+
let left = Number.POSITIVE_INFINITY;
|
|
897
|
+
let top = Number.POSITIVE_INFINITY;
|
|
898
|
+
let right = Number.NEGATIVE_INFINITY;
|
|
899
|
+
let bottom = Number.NEGATIVE_INFINITY;
|
|
900
|
+
for (const line of lines) {
|
|
901
|
+
if (line.frame.widthPx <= 0 || line.frame.heightPx <= 0) continue;
|
|
902
|
+
left = Math.min(left, line.frame.leftPx);
|
|
903
|
+
top = Math.min(top, line.frame.topPx);
|
|
904
|
+
right = Math.max(right, line.frame.leftPx + line.frame.widthPx);
|
|
905
|
+
bottom = Math.max(bottom, line.frame.topPx + line.frame.heightPx);
|
|
906
|
+
}
|
|
907
|
+
if (!Number.isFinite(left) || !Number.isFinite(top)) return null;
|
|
908
|
+
return {
|
|
909
|
+
leftPx: left,
|
|
910
|
+
topPx: top,
|
|
911
|
+
widthPx: Math.max(0, right - left),
|
|
912
|
+
heightPx: Math.max(0, bottom - top)
|
|
913
|
+
};
|
|
914
|
+
}
|
|
915
|
+
function buildHeaderFooterRegion(page, pageTopPx, zoom, kind, storyTarget, facet) {
|
|
916
|
+
const layout = page.layout;
|
|
917
|
+
const fallbackWidthTwips = layout.pageWidth - layout.marginLeft - layout.marginRight;
|
|
918
|
+
const fallbackTopTwips = kind === "header" ? layout.headerMargin ?? 720 : layout.pageHeight - layout.marginBottom;
|
|
919
|
+
const fallbackHeightTwips = kind === "header" ? Math.max(0, layout.marginTop - (layout.headerMargin ?? 720)) : Math.max(0, layout.marginBottom - (layout.footerMargin ?? 720));
|
|
920
|
+
const region = (kind === "header" ? page.regions.header : page.regions.footer) ?? {
|
|
921
|
+
kind,
|
|
922
|
+
originTwips: fallbackTopTwips,
|
|
923
|
+
widthTwips: fallbackWidthTwips,
|
|
924
|
+
heightTwips: fallbackHeightTwips,
|
|
925
|
+
fragmentCount: 0
|
|
926
|
+
};
|
|
927
|
+
const frame = {
|
|
928
|
+
leftPx: layout.marginLeft * zoom.pxPerTwip,
|
|
929
|
+
topPx: pageTopPx + region.originTwips * zoom.pxPerTwip,
|
|
930
|
+
widthPx: region.widthTwips * zoom.pxPerTwip,
|
|
931
|
+
heightPx: region.heightTwips * zoom.pxPerTwip
|
|
932
|
+
};
|
|
933
|
+
const regionBlocks = facet.getStoryBlocksForRegion(page.pageIndex, kind);
|
|
934
|
+
const blocks = projectRegionBlocks(
|
|
935
|
+
regionBlocks,
|
|
936
|
+
frame,
|
|
937
|
+
zoom.pxPerTwip,
|
|
938
|
+
page.pageId,
|
|
939
|
+
page.pageIndex,
|
|
940
|
+
kind
|
|
941
|
+
);
|
|
942
|
+
return {
|
|
943
|
+
storyTarget,
|
|
944
|
+
region,
|
|
945
|
+
frame,
|
|
946
|
+
blocks
|
|
947
|
+
};
|
|
948
|
+
}
|
|
949
|
+
function buildFootnoteRegions(page, pageTopPx, zoom, facet) {
|
|
950
|
+
const footnoteRegions = page.regions.footnotes;
|
|
951
|
+
if (!footnoteRegions || footnoteRegions.length === 0) return [];
|
|
952
|
+
const regionBlocks = facet.getStoryBlocksForRegion(
|
|
953
|
+
page.pageIndex,
|
|
954
|
+
"footnote-area"
|
|
955
|
+
);
|
|
956
|
+
if (regionBlocks.length === 0) return [];
|
|
957
|
+
const results = [];
|
|
958
|
+
let cursor = 0;
|
|
959
|
+
for (const region of footnoteRegions) {
|
|
960
|
+
const frame = {
|
|
961
|
+
leftPx: page.layout.marginLeft * zoom.pxPerTwip,
|
|
962
|
+
topPx: pageTopPx + region.originTwips * zoom.pxPerTwip,
|
|
963
|
+
widthPx: region.widthTwips * zoom.pxPerTwip,
|
|
964
|
+
heightPx: region.heightTwips * zoom.pxPerTwip
|
|
965
|
+
};
|
|
966
|
+
const blocksForThisRegion = footnoteRegions.length === 1 ? regionBlocks : regionBlocks.slice(cursor, cursor + region.fragmentCount);
|
|
967
|
+
cursor += region.fragmentCount;
|
|
968
|
+
const blocks = projectRegionBlocks(
|
|
969
|
+
blocksForThisRegion,
|
|
970
|
+
frame,
|
|
971
|
+
zoom.pxPerTwip,
|
|
972
|
+
page.pageId,
|
|
973
|
+
page.pageIndex,
|
|
974
|
+
"footnote-area"
|
|
975
|
+
);
|
|
976
|
+
const firstNote = page.noteAllocations.find(
|
|
977
|
+
(alloc) => alloc.noteKind === "footnote"
|
|
978
|
+
);
|
|
979
|
+
const storyTarget = firstNote ? { kind: "footnote", noteId: firstNote.noteId } : MAIN_STORY_TARGET;
|
|
980
|
+
results.push({
|
|
981
|
+
storyTarget,
|
|
982
|
+
region,
|
|
983
|
+
frame,
|
|
984
|
+
blocks
|
|
985
|
+
});
|
|
986
|
+
}
|
|
987
|
+
return results;
|
|
988
|
+
}
|
|
989
|
+
function projectRegionBlocks(regionBlocks, regionFrame, pxPerTwip, pageId, pageIndex, regionKind) {
|
|
990
|
+
const blocks = [];
|
|
991
|
+
let y = regionFrame.topPx;
|
|
992
|
+
for (let i = 0; i < regionBlocks.length; i += 1) {
|
|
993
|
+
const regionBlock = regionBlocks[i];
|
|
994
|
+
const blockHeightPx = Math.max(0, regionBlock.heightTwips) * pxPerTwip;
|
|
995
|
+
const blockFrame = {
|
|
996
|
+
leftPx: regionFrame.leftPx,
|
|
997
|
+
topPx: y,
|
|
998
|
+
widthPx: regionFrame.widthPx,
|
|
999
|
+
heightPx: blockHeightPx
|
|
1000
|
+
};
|
|
1001
|
+
const fragment = {
|
|
1002
|
+
fragmentId: regionBlock.fragmentId,
|
|
1003
|
+
blockId: regionBlock.blockId,
|
|
1004
|
+
pageId,
|
|
1005
|
+
pageIndex,
|
|
1006
|
+
regionKind,
|
|
1007
|
+
from: regionBlock.runtimeFromOffset,
|
|
1008
|
+
to: regionBlock.runtimeToOffset,
|
|
1009
|
+
heightTwips: regionBlock.heightTwips,
|
|
1010
|
+
orderInRegion: i
|
|
1011
|
+
};
|
|
1012
|
+
blocks.push({
|
|
1013
|
+
fragment,
|
|
1014
|
+
frame: blockFrame,
|
|
1015
|
+
kind: classifyBlockKind(regionBlock.blockId),
|
|
1016
|
+
lines: [],
|
|
1017
|
+
blockDecorations: []
|
|
1018
|
+
});
|
|
1019
|
+
y += blockHeightPx;
|
|
1020
|
+
}
|
|
1021
|
+
return blocks;
|
|
1022
|
+
}
|
|
1023
|
+
function buildAnchorIndex(pages, pendingDeltas = [], pxPerTwip = 1, decorationIndex = EMPTY_DECORATION_INDEX) {
|
|
1024
|
+
const byRuntimeOffset = /* @__PURE__ */ new Map();
|
|
1025
|
+
const byRuntimeOffsetByStory = /* @__PURE__ */ new Map();
|
|
1026
|
+
const byFragmentId = /* @__PURE__ */ new Map();
|
|
1027
|
+
const byBlockId = /* @__PURE__ */ new Map();
|
|
1028
|
+
const byPageIndex = /* @__PURE__ */ new Map();
|
|
1029
|
+
const tableCellRects = /* @__PURE__ */ new Map();
|
|
1030
|
+
const tableColumnEdges = /* @__PURE__ */ new Map();
|
|
1031
|
+
const tableRowEdges = /* @__PURE__ */ new Map();
|
|
1032
|
+
const recordBlock = (block, offsetMap) => {
|
|
1033
|
+
byFragmentId.set(block.fragment.fragmentId, block.frame);
|
|
1034
|
+
byBlockId.set(block.fragment.blockId, block.frame);
|
|
1035
|
+
offsetMap.set(block.fragment.from, block.frame);
|
|
1036
|
+
for (const line of block.lines) {
|
|
1037
|
+
for (const anchor of line.anchors) {
|
|
1038
|
+
offsetMap.set(anchor.runtimeOffset, anchor.frame);
|
|
1039
|
+
}
|
|
1040
|
+
}
|
|
1041
|
+
if (block.kind === "table" && block.tablePlan) {
|
|
1042
|
+
recordTableAnchors(
|
|
1043
|
+
block.fragment.blockId,
|
|
1044
|
+
block.frame,
|
|
1045
|
+
block.tablePlan,
|
|
1046
|
+
pxPerTwip,
|
|
1047
|
+
tableCellRects,
|
|
1048
|
+
tableColumnEdges,
|
|
1049
|
+
tableRowEdges
|
|
1050
|
+
);
|
|
1051
|
+
}
|
|
1052
|
+
};
|
|
1053
|
+
const recordStoryRegion = (region) => {
|
|
1054
|
+
const storyKey = storyTargetKey(region.storyTarget);
|
|
1055
|
+
let storyMap = byRuntimeOffsetByStory.get(storyKey);
|
|
1056
|
+
if (!storyMap) {
|
|
1057
|
+
storyMap = /* @__PURE__ */ new Map();
|
|
1058
|
+
byRuntimeOffsetByStory.set(storyKey, storyMap);
|
|
1059
|
+
}
|
|
1060
|
+
for (const block of region.blocks) {
|
|
1061
|
+
recordBlock(block, storyMap);
|
|
1062
|
+
}
|
|
1063
|
+
};
|
|
1064
|
+
for (const page of pages) {
|
|
1065
|
+
byPageIndex.set(page.page.pageIndex, page.frame);
|
|
1066
|
+
for (const block of page.regions.body.blocks) {
|
|
1067
|
+
recordBlock(block, byRuntimeOffset);
|
|
1068
|
+
}
|
|
1069
|
+
if (page.regions.header) recordStoryRegion(page.regions.header);
|
|
1070
|
+
if (page.regions.footer) recordStoryRegion(page.regions.footer);
|
|
1071
|
+
if (page.regions.footnotes) {
|
|
1072
|
+
for (const footnote of page.regions.footnotes) {
|
|
1073
|
+
recordStoryRegion(footnote);
|
|
1074
|
+
}
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
1077
|
+
const shiftForDeltas = (offset) => {
|
|
1078
|
+
if (pendingDeltas.length === 0) return offset;
|
|
1079
|
+
return offset - sumDeltasBefore(pendingDeltas, offset);
|
|
1080
|
+
};
|
|
1081
|
+
const resolveByRuntimeOffset = (offset, story) => {
|
|
1082
|
+
const lookup = shiftForDeltas(offset);
|
|
1083
|
+
const targetMap = story && story.kind !== "main" ? byRuntimeOffsetByStory.get(storyTargetKey(story)) ?? byRuntimeOffset : byRuntimeOffset;
|
|
1084
|
+
const exact = targetMap.get(lookup);
|
|
1085
|
+
if (exact) return exact;
|
|
1086
|
+
let best = null;
|
|
1087
|
+
let bestDistance = Number.POSITIVE_INFINITY;
|
|
1088
|
+
for (const [key, rect2] of targetMap) {
|
|
1089
|
+
const distance = Math.abs(key - lookup);
|
|
1090
|
+
if (distance < bestDistance) {
|
|
1091
|
+
best = rect2;
|
|
1092
|
+
bestDistance = distance;
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1095
|
+
return best;
|
|
1096
|
+
};
|
|
1097
|
+
return {
|
|
1098
|
+
byRuntimeOffset(offset, story) {
|
|
1099
|
+
return resolveByRuntimeOffset(offset, story);
|
|
1100
|
+
},
|
|
1101
|
+
byBlockId(blockId) {
|
|
1102
|
+
return byBlockId.get(blockId) ?? null;
|
|
1103
|
+
},
|
|
1104
|
+
byFragmentId(fragmentId) {
|
|
1105
|
+
return byFragmentId.get(fragmentId) ?? null;
|
|
1106
|
+
},
|
|
1107
|
+
byPageIndex(pageIndex) {
|
|
1108
|
+
return byPageIndex.get(pageIndex) ?? null;
|
|
1109
|
+
},
|
|
1110
|
+
bySelection(fromOffset, toOffset, story) {
|
|
1111
|
+
const lo = Math.min(fromOffset, toOffset);
|
|
1112
|
+
const hi = Math.max(fromOffset, toOffset);
|
|
1113
|
+
if (lo === hi) {
|
|
1114
|
+
return resolveByRuntimeOffset(lo, story);
|
|
1115
|
+
}
|
|
1116
|
+
const loShifted = shiftForDeltas(lo);
|
|
1117
|
+
const hiShifted = shiftForDeltas(hi);
|
|
1118
|
+
const targetMap = story && story.kind !== "main" ? byRuntimeOffsetByStory.get(storyTargetKey(story)) ?? byRuntimeOffset : byRuntimeOffset;
|
|
1119
|
+
let union = null;
|
|
1120
|
+
for (const [key, rect2] of targetMap) {
|
|
1121
|
+
if (key < loShifted || key >= hiShifted) continue;
|
|
1122
|
+
union = unionRects(union, rect2);
|
|
1123
|
+
}
|
|
1124
|
+
if (union) return union;
|
|
1125
|
+
const fromRect = resolveByRuntimeOffset(lo, story);
|
|
1126
|
+
const toRect = resolveByRuntimeOffset(hi - 1, story);
|
|
1127
|
+
return unionRects(fromRect, toRect);
|
|
1128
|
+
},
|
|
1129
|
+
byTableCell(tableBlockId, rowIndex, columnIndex) {
|
|
1130
|
+
return tableCellRects.get(`${tableBlockId}:${rowIndex}:${columnIndex}`) ?? null;
|
|
1131
|
+
},
|
|
1132
|
+
byTableColumnEdge(tableBlockId, columnIndex) {
|
|
1133
|
+
return tableColumnEdges.get(`${tableBlockId}:${columnIndex}`) ?? null;
|
|
1134
|
+
},
|
|
1135
|
+
byTableRowEdge(tableBlockId, rowIndex) {
|
|
1136
|
+
return tableRowEdges.get(`${tableBlockId}:${rowIndex}`) ?? null;
|
|
1137
|
+
},
|
|
1138
|
+
// P9 Phase A — chrome-kind resolvers sourced from the resolved
|
|
1139
|
+
// decoration index. Empty by default (the initial frame build passes
|
|
1140
|
+
// `EMPTY_DECORATION_INDEX` until decoration resolution runs); the
|
|
1141
|
+
// kernel re-invokes `buildAnchorIndex` with the resolved index so the
|
|
1142
|
+
// final anchor index carries chrome-aware lookups.
|
|
1143
|
+
byScopeId(scopeId) {
|
|
1144
|
+
return decorationIndex.workflow.filter((decoration) => decoration.refId === scopeId).map((decoration) => decoration.frame);
|
|
1145
|
+
},
|
|
1146
|
+
byCommentId(commentId) {
|
|
1147
|
+
const match = decorationIndex.comments.find(
|
|
1148
|
+
(decoration) => decoration.refId === commentId
|
|
1149
|
+
);
|
|
1150
|
+
return match?.frame ?? null;
|
|
1151
|
+
},
|
|
1152
|
+
byRevisionId(revisionId) {
|
|
1153
|
+
const match = decorationIndex.revisions.find(
|
|
1154
|
+
(decoration) => decoration.refId === revisionId
|
|
1155
|
+
);
|
|
1156
|
+
return match?.frame ?? null;
|
|
1157
|
+
},
|
|
1158
|
+
// Refactor/05 Slice 7c substrate: object-specific index. Falls back
|
|
1159
|
+
// to `byBlockId` because the render kernel does not yet carry
|
|
1160
|
+
// per-object metadata on anchor frames — the layout facet would
|
|
1161
|
+
// need to emit `byObjectId` entries on the page graph. When that
|
|
1162
|
+
// follow-up ships, populate a dedicated `byObjectIdMap` here and
|
|
1163
|
+
// consult it before the `byBlockId` fallback. The fallback is
|
|
1164
|
+
// correct for block-level drawings (whose object id equals their
|
|
1165
|
+
// block id); it is `heuristic` for inline images (which share
|
|
1166
|
+
// their block id with the enclosing paragraph). `object-handles.ts`
|
|
1167
|
+
// tags those handles `precision: "heuristic"` accordingly.
|
|
1168
|
+
byObjectId(objectId) {
|
|
1169
|
+
return byBlockId.get(objectId) ?? null;
|
|
1170
|
+
}
|
|
1171
|
+
};
|
|
1172
|
+
}
|
|
1173
|
+
function recordTableAnchors(tableBlockId, blockFrame, plan, pxPerTwip, cellRects, columnEdges, rowEdges) {
|
|
1174
|
+
if (!plan) return;
|
|
1175
|
+
const columnCount = plan.columnsTwips.length;
|
|
1176
|
+
if (columnCount === 0) return;
|
|
1177
|
+
const columnLeftsPx = [blockFrame.leftPx];
|
|
1178
|
+
for (let i = 0; i < columnCount; i += 1) {
|
|
1179
|
+
columnLeftsPx.push(
|
|
1180
|
+
columnLeftsPx[i] + (plan.columnsTwips[i] ?? 0) * pxPerTwip
|
|
1181
|
+
);
|
|
1182
|
+
}
|
|
1183
|
+
const rowCount = Math.max(
|
|
1184
|
+
1,
|
|
1185
|
+
plan.bandClasses.rows.length || plan.bandClasses.cells.reduce(
|
|
1186
|
+
(max, c) => Math.max(max, c.rowIndex + 1),
|
|
1187
|
+
0
|
|
1188
|
+
)
|
|
1189
|
+
);
|
|
1190
|
+
const rowHeightPx = rowCount > 0 ? blockFrame.heightPx / rowCount : blockFrame.heightPx;
|
|
1191
|
+
const rowTopsPx = [];
|
|
1192
|
+
for (let r = 0; r <= rowCount; r += 1) {
|
|
1193
|
+
rowTopsPx.push(blockFrame.topPx + r * rowHeightPx);
|
|
1194
|
+
}
|
|
1195
|
+
for (const cell of plan.bandClasses.cells) {
|
|
1196
|
+
const sameRow = plan.bandClasses.cells.filter((c) => c.rowIndex === cell.rowIndex);
|
|
1197
|
+
const sorted = [...sameRow].sort((a, b) => a.columnIndex - b.columnIndex);
|
|
1198
|
+
const idx = sorted.findIndex((c) => c === cell);
|
|
1199
|
+
const next = sorted[idx + 1];
|
|
1200
|
+
const columnSpan = (next?.columnIndex ?? columnCount) - cell.columnIndex;
|
|
1201
|
+
const left = columnLeftsPx[cell.columnIndex] ?? blockFrame.leftPx;
|
|
1202
|
+
const right = columnLeftsPx[cell.columnIndex + columnSpan] ?? blockFrame.leftPx + blockFrame.widthPx;
|
|
1203
|
+
const top = rowTopsPx[cell.rowIndex] ?? blockFrame.topPx;
|
|
1204
|
+
const bottom = rowTopsPx[cell.rowIndex + 1] ?? blockFrame.topPx + blockFrame.heightPx;
|
|
1205
|
+
cellRects.set(`${tableBlockId}:${cell.rowIndex}:${cell.columnIndex}`, {
|
|
1206
|
+
leftPx: left,
|
|
1207
|
+
topPx: top,
|
|
1208
|
+
widthPx: Math.max(0, right - left),
|
|
1209
|
+
heightPx: Math.max(0, bottom - top)
|
|
1210
|
+
});
|
|
1211
|
+
}
|
|
1212
|
+
for (const handle of plan.columnResizeHandles) {
|
|
1213
|
+
const x = blockFrame.leftPx + handle.originTwips * pxPerTwip;
|
|
1214
|
+
columnEdges.set(`${tableBlockId}:${handle.columnIndex}`, {
|
|
1215
|
+
leftPx: x,
|
|
1216
|
+
topPx: blockFrame.topPx,
|
|
1217
|
+
widthPx: 0,
|
|
1218
|
+
heightPx: handle.heightTwips * pxPerTwip
|
|
1219
|
+
});
|
|
1220
|
+
}
|
|
1221
|
+
for (let r = 0; r < rowCount - 1; r += 1) {
|
|
1222
|
+
const y = rowTopsPx[r + 1] ?? blockFrame.topPx + blockFrame.heightPx;
|
|
1223
|
+
rowEdges.set(`${tableBlockId}:${r}`, {
|
|
1224
|
+
leftPx: blockFrame.leftPx,
|
|
1225
|
+
topPx: y,
|
|
1226
|
+
widthPx: blockFrame.widthPx,
|
|
1227
|
+
heightPx: 0
|
|
1228
|
+
});
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
function unionRects(a, b) {
|
|
1232
|
+
if (!a) return b ?? null;
|
|
1233
|
+
if (!b) return a;
|
|
1234
|
+
const left = Math.min(a.leftPx, b.leftPx);
|
|
1235
|
+
const top = Math.min(a.topPx, b.topPx);
|
|
1236
|
+
const right = Math.max(a.leftPx + a.widthPx, b.leftPx + b.widthPx);
|
|
1237
|
+
const bottom = Math.max(a.topPx + a.heightPx, b.topPx + b.heightPx);
|
|
1238
|
+
return {
|
|
1239
|
+
leftPx: left,
|
|
1240
|
+
topPx: top,
|
|
1241
|
+
widthPx: right - left,
|
|
1242
|
+
heightPx: bottom - top
|
|
1243
|
+
};
|
|
1244
|
+
}
|
|
1245
|
+
function buildDecorationIndex(pages) {
|
|
1246
|
+
const workflow = [];
|
|
1247
|
+
const comments = [];
|
|
1248
|
+
const revisions = [];
|
|
1249
|
+
const search = [];
|
|
1250
|
+
const locked = [];
|
|
1251
|
+
for (const page of pages) {
|
|
1252
|
+
for (const block of page.regions.body.blocks) {
|
|
1253
|
+
for (const decoration of block.blockDecorations) {
|
|
1254
|
+
switch (decoration.kind) {
|
|
1255
|
+
case "workflow":
|
|
1256
|
+
workflow.push(decoration);
|
|
1257
|
+
break;
|
|
1258
|
+
case "comment":
|
|
1259
|
+
comments.push(decoration);
|
|
1260
|
+
break;
|
|
1261
|
+
case "revision":
|
|
1262
|
+
revisions.push(decoration);
|
|
1263
|
+
break;
|
|
1264
|
+
case "search":
|
|
1265
|
+
search.push(decoration);
|
|
1266
|
+
break;
|
|
1267
|
+
case "locked":
|
|
1268
|
+
locked.push(decoration);
|
|
1269
|
+
break;
|
|
1270
|
+
}
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
1274
|
+
return { workflow, comments, revisions, search, locked };
|
|
1275
|
+
}
|
|
1276
|
+
function extractRevisionFromPageId(pageId) {
|
|
1277
|
+
const match = /^page-(\d+)-/.exec(pageId);
|
|
1278
|
+
if (!match) return pageId;
|
|
1279
|
+
return Number(match[1]);
|
|
1280
|
+
}
|
|
1281
|
+
|
|
113
1282
|
// src/core/selection/review-anchors.ts
|
|
114
1283
|
function detachReviewAnchor(lastKnownRange, reason) {
|
|
115
1284
|
return createDetachedAnchor(lastKnownRange, reason);
|
|
@@ -5112,6 +6281,11 @@ function freezeNumberingLayoutFacts(numbering) {
|
|
|
5112
6281
|
if (numbering.numberingSourceRef) Object.freeze(numbering.numberingSourceRef);
|
|
5113
6282
|
if (numbering.numberingInstanceSourceRef) Object.freeze(numbering.numberingInstanceSourceRef);
|
|
5114
6283
|
if (numbering.abstractNumberingSourceRef) Object.freeze(numbering.abstractNumberingSourceRef);
|
|
6284
|
+
if (numbering.markerTextPosture) Object.freeze(numbering.markerTextPosture);
|
|
6285
|
+
if (numbering.pictureBulletPosture) {
|
|
6286
|
+
if (numbering.pictureBulletPosture.sourceRef) Object.freeze(numbering.pictureBulletPosture.sourceRef);
|
|
6287
|
+
Object.freeze(numbering.pictureBulletPosture);
|
|
6288
|
+
}
|
|
5115
6289
|
if (numbering.markerLane) Object.freeze(numbering.markerLane);
|
|
5116
6290
|
if (numbering.textColumn) Object.freeze(numbering.textColumn);
|
|
5117
6291
|
if (numbering.tabStops) {
|
|
@@ -6087,8 +7261,17 @@ function collectNumberingLayoutFacts(block) {
|
|
|
6087
7261
|
...block.resolvedNumbering?.format !== void 0 ? { format: block.resolvedNumbering.format } : {},
|
|
6088
7262
|
...block.resolvedNumbering?.formatPosture !== void 0 ? { formatPosture: { ...block.resolvedNumbering.formatPosture } } : {},
|
|
6089
7263
|
...block.numberingPrefix !== void 0 ? { markerText: block.numberingPrefix } : {},
|
|
7264
|
+
...block.resolvedNumbering?.markerTextPosture !== void 0 ? { markerTextPosture: { ...block.resolvedNumbering.markerTextPosture } } : {},
|
|
6090
7265
|
...block.numberingSuffix !== void 0 ? { markerSuffix: block.numberingSuffix } : {},
|
|
6091
7266
|
...block.resolvedNumbering?.geometry.markerJustification !== void 0 ? { markerJustification: block.resolvedNumbering.geometry.markerJustification } : {},
|
|
7267
|
+
...block.resolvedNumbering?.picBulletId !== void 0 ? { picBulletId: block.resolvedNumbering.picBulletId } : {},
|
|
7268
|
+
...block.resolvedNumbering?.picBulletMediaId !== void 0 ? { picBulletMediaId: block.resolvedNumbering.picBulletMediaId } : {},
|
|
7269
|
+
...block.resolvedNumbering?.pictureBulletPosture !== void 0 ? {
|
|
7270
|
+
pictureBulletPosture: {
|
|
7271
|
+
...block.resolvedNumbering.pictureBulletPosture,
|
|
7272
|
+
...block.resolvedNumbering.pictureBulletPosture.sourceRef !== void 0 ? { sourceRef: { ...block.resolvedNumbering.pictureBulletPosture.sourceRef } } : {}
|
|
7273
|
+
}
|
|
7274
|
+
} : {},
|
|
6092
7275
|
...markerLane ? {
|
|
6093
7276
|
markerLane: {
|
|
6094
7277
|
startTwips: markerLane.start,
|
|
@@ -6903,7 +8086,7 @@ function fnv1a(input) {
|
|
|
6903
8086
|
|
|
6904
8087
|
// src/runtime/layout/layout-engine-version.ts
|
|
6905
8088
|
var LAYOUT_ENGINE_VERSION = 93;
|
|
6906
|
-
var LAYCACHE_SCHEMA_VERSION =
|
|
8089
|
+
var LAYCACHE_SCHEMA_VERSION = 13;
|
|
6907
8090
|
|
|
6908
8091
|
// src/runtime/layout/layout-engine-instance.ts
|
|
6909
8092
|
var FULL_VIEWPORT_WINDOW_KEY = "full";
|
|
@@ -7941,33 +9124,6 @@ function resolveProjectedRuntimeRange(offsetMap, from, to) {
|
|
|
7941
9124
|
return { from: runtimeFrom, to: runtimeTo };
|
|
7942
9125
|
}
|
|
7943
9126
|
|
|
7944
|
-
// src/runtime/render/render-frame-types.ts
|
|
7945
|
-
var DEFAULT_PX_PER_TWIP = 96 / 1440;
|
|
7946
|
-
var PAGE_STACK_GAP_PX = 48;
|
|
7947
|
-
function resolveDefaultZoom(input = {}) {
|
|
7948
|
-
return {
|
|
7949
|
-
pxPerTwip: input.pxPerTwip ?? DEFAULT_PX_PER_TWIP,
|
|
7950
|
-
viewportWidthPx: input.viewportWidthPx ?? 900,
|
|
7951
|
-
fitMode: input.fitMode ?? "fixed"
|
|
7952
|
-
};
|
|
7953
|
-
}
|
|
7954
|
-
var EMPTY_DECORATION_INDEX = Object.freeze({
|
|
7955
|
-
workflow: Object.freeze([]),
|
|
7956
|
-
comments: Object.freeze([]),
|
|
7957
|
-
revisions: Object.freeze([]),
|
|
7958
|
-
search: Object.freeze([]),
|
|
7959
|
-
locked: Object.freeze([])
|
|
7960
|
-
});
|
|
7961
|
-
function defaultChromeReservations(layout, zoom) {
|
|
7962
|
-
return {
|
|
7963
|
-
railLaneTwips: 360,
|
|
7964
|
-
balloonLaneTwips: 2160,
|
|
7965
|
-
footnoteAreaTwips: 0,
|
|
7966
|
-
pageFrameWidthPx: layout.pageWidth * zoom.pxPerTwip,
|
|
7967
|
-
pageFrameHeightPx: layout.pageHeight * zoom.pxPerTwip
|
|
7968
|
-
};
|
|
7969
|
-
}
|
|
7970
|
-
|
|
7971
9127
|
// src/runtime/markdown-sanitizer.ts
|
|
7972
9128
|
function sanitizeMarkdown(raw) {
|
|
7973
9129
|
let sanitized = false;
|
|
@@ -8080,6 +9236,16 @@ export {
|
|
|
8080
9236
|
DEFAULT_UNKNOWN_BEHAVIOR,
|
|
8081
9237
|
DEFAULT_REGISTRY_ENTRIES,
|
|
8082
9238
|
createScopeTagRegistry,
|
|
9239
|
+
PREDICTED_LANE_COUNTERS,
|
|
9240
|
+
startPerfProbe,
|
|
9241
|
+
finishPerfProbe,
|
|
9242
|
+
recordPerfSample,
|
|
9243
|
+
incrementInvalidationCounter,
|
|
9244
|
+
createPagePatchPlan,
|
|
9245
|
+
DEFAULT_PX_PER_TWIP,
|
|
9246
|
+
PAGE_STACK_GAP_PX,
|
|
9247
|
+
resolveDefaultZoom,
|
|
9248
|
+
createRenderKernel,
|
|
8083
9249
|
detachReviewAnchor,
|
|
8084
9250
|
mapReviewAnchor,
|
|
8085
9251
|
getAnchorRange,
|
|
@@ -8127,11 +9293,6 @@ export {
|
|
|
8127
9293
|
searchProjectedSurfaceText,
|
|
8128
9294
|
searchSecondaryStories,
|
|
8129
9295
|
projectSurfaceText,
|
|
8130
|
-
DEFAULT_PX_PER_TWIP,
|
|
8131
|
-
PAGE_STACK_GAP_PX,
|
|
8132
|
-
resolveDefaultZoom,
|
|
8133
|
-
EMPTY_DECORATION_INDEX,
|
|
8134
|
-
defaultChromeReservations,
|
|
8135
9296
|
sanitizeMarkdown,
|
|
8136
9297
|
sha256Hex,
|
|
8137
9298
|
ISSUE_METADATA_ID,
|