@beyondwork/docx-react-component 1.0.103 → 1.0.105
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 +66 -1
- package/src/api/v3/_runtime-handle.ts +2 -0
- package/src/api/v3/ai/_pe2-evidence.ts +153 -0
- package/src/api/v3/ai/bundle.ts +13 -5
- package/src/api/v3/ai/inspect.ts +7 -1
- package/src/api/v3/ai/outline.ts +2 -7
- package/src/api/v3/ai/replacement.ts +113 -0
- package/src/api/v3/runtime/geometry.ts +79 -0
- package/src/api/v3/ui/_types.ts +86 -0
- package/src/api/v3/ui/index.ts +5 -0
- package/src/api/v3/ui/overlays.ts +104 -0
- package/src/io/ooxml/parse-drawing.ts +99 -1
- package/src/io/ooxml/parse-fields.ts +27 -6
- package/src/io/ooxml/parse-shapes.ts +130 -0
- package/src/model/canonical-document.ts +34 -3
- package/src/model/canonical-layout-inputs.ts +979 -0
- package/src/model/layout/index.ts +9 -0
- package/src/model/layout/page-graph-types.ts +150 -0
- package/src/model/layout/runtime-page-graph-types.ts +23 -0
- package/src/runtime/collab/runtime-collab-sync.ts +3 -3
- package/src/runtime/debug/build-debug-inspector-snapshot.ts +17 -4
- package/src/runtime/document-runtime.ts +30 -14
- package/src/runtime/event-refresh-hints.ts +35 -5
- package/src/runtime/formatting/formatting-context.ts +110 -9
- package/src/runtime/formatting/index.ts +2 -0
- package/src/runtime/formatting/layout-inputs.ts +67 -3
- package/src/runtime/geometry/caret-geometry.ts +82 -10
- package/src/runtime/geometry/geometry-facet.ts +44 -0
- package/src/runtime/geometry/geometry-index.ts +1268 -0
- package/src/runtime/geometry/geometry-types.ts +227 -1
- package/src/runtime/geometry/index.ts +26 -0
- package/src/runtime/geometry/inert-geometry-facet.ts +3 -0
- package/src/runtime/geometry/object-handles.ts +7 -4
- package/src/runtime/geometry/replacement-envelope.ts +41 -2
- package/src/runtime/layout/layout-engine-instance.ts +2 -0
- package/src/runtime/layout/layout-engine-version.ts +44 -1
- package/src/runtime/layout/page-graph.ts +877 -2
- package/src/runtime/layout/project-block-fragments.ts +101 -1
- package/src/runtime/layout/public-facet.ts +152 -0
- package/src/runtime/prerender/graph-canonicalize.ts +44 -0
- package/src/runtime/surface-projection.ts +43 -3
- package/src/runtime/workflow/coordinator.ts +57 -11
- package/src/ui/ui-controller-factory.ts +11 -0
- package/src/ui-tailwind/chrome-overlay/tw-page-stack-overlay-layer.tsx +3 -0
|
@@ -235,11 +235,27 @@ function emitSlicedParagraph(
|
|
|
235
235
|
...deriveStyleMetadata(block),
|
|
236
236
|
kind: "paragraph-slice",
|
|
237
237
|
paragraphLineRange: slice.lineRange,
|
|
238
|
+
continuation: buildParagraphContinuationCursor(slice, i, slices.length),
|
|
238
239
|
};
|
|
239
240
|
emit(slice.pageIndex, fragment);
|
|
240
241
|
}
|
|
241
242
|
}
|
|
242
243
|
|
|
244
|
+
function buildParagraphContinuationCursor(
|
|
245
|
+
slice: ParagraphLineSlice,
|
|
246
|
+
sequenceIndex: number,
|
|
247
|
+
sliceCount: number,
|
|
248
|
+
): NonNullable<RuntimeBlockFragment["continuation"]> {
|
|
249
|
+
return {
|
|
250
|
+
kind: "paragraph",
|
|
251
|
+
sequenceIndex,
|
|
252
|
+
sliceCount,
|
|
253
|
+
lineRange: slice.lineRange,
|
|
254
|
+
continuesFromPreviousPage: slice.lineRange.from > 0,
|
|
255
|
+
continuesToNextPage: slice.lineRange.to < slice.lineRange.totalLines,
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
|
|
243
259
|
function estimateSliceHeightFromLines(lineRange: {
|
|
244
260
|
from: number;
|
|
245
261
|
to: number;
|
|
@@ -259,7 +275,7 @@ function estimateSliceHeightFromLines(lineRange: {
|
|
|
259
275
|
* every continuation page.
|
|
260
276
|
*/
|
|
261
277
|
function emitSlicedTable(
|
|
262
|
-
block: SurfaceBlockSnapshot,
|
|
278
|
+
block: Extract<SurfaceBlockSnapshot, { kind: "table" }>,
|
|
263
279
|
slices: readonly TableRowSlice[],
|
|
264
280
|
emit: (pageIndex: number, fragment: FragmentWithoutPageId) => void,
|
|
265
281
|
): void {
|
|
@@ -276,12 +292,96 @@ function emitSlicedTable(
|
|
|
276
292
|
...deriveStyleMetadata(block),
|
|
277
293
|
kind: "table-slice",
|
|
278
294
|
tableRowRange: slice.rowRange,
|
|
295
|
+
continuation: buildTableContinuationCursor(block, slice, i, slices.length),
|
|
279
296
|
...(slice.columnIndex !== undefined ? { columnIndex: slice.columnIndex } : {}),
|
|
280
297
|
};
|
|
281
298
|
emit(slice.pageIndex, fragment);
|
|
282
299
|
}
|
|
283
300
|
}
|
|
284
301
|
|
|
302
|
+
function buildTableContinuationCursor(
|
|
303
|
+
block: Extract<SurfaceBlockSnapshot, { kind: "table" }>,
|
|
304
|
+
slice: TableRowSlice,
|
|
305
|
+
sequenceIndex: number,
|
|
306
|
+
sliceCount: number,
|
|
307
|
+
): NonNullable<RuntimeBlockFragment["continuation"]> {
|
|
308
|
+
return {
|
|
309
|
+
kind: "table",
|
|
310
|
+
sequenceIndex,
|
|
311
|
+
sliceCount,
|
|
312
|
+
rowRange: slice.rowRange,
|
|
313
|
+
continuesFromPreviousPage: slice.rowRange.from > 0,
|
|
314
|
+
continuesToNextPage: slice.rowRange.to < slice.rowRange.totalRows,
|
|
315
|
+
repeatedHeaderRowIndexes:
|
|
316
|
+
slice.rowRange.from > 0
|
|
317
|
+
? collectRepeatedHeaderRowIndexes(block, slice.rowRange.from)
|
|
318
|
+
: [],
|
|
319
|
+
verticalMergeCarry: collectVerticalMergeCarry(block, slice.rowRange.from),
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
function collectRepeatedHeaderRowIndexes(
|
|
324
|
+
block: Extract<SurfaceBlockSnapshot, { kind: "table" }>,
|
|
325
|
+
startRow: number,
|
|
326
|
+
): number[] {
|
|
327
|
+
const headerRows: number[] = [];
|
|
328
|
+
for (let rowIndex = 0; rowIndex < block.rows.length; rowIndex += 1) {
|
|
329
|
+
if (rowIndex >= startRow) break;
|
|
330
|
+
if (block.rows[rowIndex]?.isHeader === true) headerRows.push(rowIndex);
|
|
331
|
+
}
|
|
332
|
+
return headerRows;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
function collectVerticalMergeCarry(
|
|
336
|
+
block: Extract<SurfaceBlockSnapshot, { kind: "table" }>,
|
|
337
|
+
startRow: number,
|
|
338
|
+
): Array<{ columnIndex: number; restartRowIndex: number }> {
|
|
339
|
+
if (startRow <= 0) return [];
|
|
340
|
+
|
|
341
|
+
const activeByColumn = new Map<number, number>();
|
|
342
|
+
for (let rowIndex = 0; rowIndex < startRow; rowIndex += 1) {
|
|
343
|
+
visitRowCells(block.rows[rowIndex], (columnIndex, span, verticalMerge) => {
|
|
344
|
+
for (let column = columnIndex; column < columnIndex + span; column += 1) {
|
|
345
|
+
if (verticalMerge === "restart") {
|
|
346
|
+
activeByColumn.set(column, rowIndex);
|
|
347
|
+
} else if (verticalMerge !== "continue") {
|
|
348
|
+
activeByColumn.delete(column);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
const carried = new Map<number, number>();
|
|
355
|
+
visitRowCells(block.rows[startRow], (columnIndex, span, verticalMerge) => {
|
|
356
|
+
if (verticalMerge !== "continue") return;
|
|
357
|
+
for (let column = columnIndex; column < columnIndex + span; column += 1) {
|
|
358
|
+
const restartRowIndex = activeByColumn.get(column);
|
|
359
|
+
if (restartRowIndex !== undefined) carried.set(column, restartRowIndex);
|
|
360
|
+
}
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
return [...carried]
|
|
364
|
+
.sort(([a], [b]) => a - b)
|
|
365
|
+
.map(([columnIndex, restartRowIndex]) => ({ columnIndex, restartRowIndex }));
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
function visitRowCells(
|
|
369
|
+
row: Extract<SurfaceBlockSnapshot, { kind: "table" }>["rows"][number] | undefined,
|
|
370
|
+
visit: (
|
|
371
|
+
columnIndex: number,
|
|
372
|
+
span: number,
|
|
373
|
+
verticalMerge: "restart" | "continue" | null,
|
|
374
|
+
) => void,
|
|
375
|
+
): void {
|
|
376
|
+
if (!row) return;
|
|
377
|
+
let columnIndex = Math.max(0, row.gridBefore ?? 0);
|
|
378
|
+
for (const cell of row.cells) {
|
|
379
|
+
const span = Math.max(1, cell.gridSpan || cell.colspan || 1);
|
|
380
|
+
visit(columnIndex, span, cell.verticalMerge);
|
|
381
|
+
columnIndex += span;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
|
|
285
385
|
function estimateSliceHeightFromRows(rowRange: {
|
|
286
386
|
from: number;
|
|
287
387
|
to: number;
|
|
@@ -25,12 +25,16 @@ import type {
|
|
|
25
25
|
} from "./page-story-resolver.ts";
|
|
26
26
|
import type {
|
|
27
27
|
RuntimeBlockFragment,
|
|
28
|
+
RuntimeLayoutContinuationCursor,
|
|
29
|
+
RuntimeLayoutDivergence,
|
|
28
30
|
RuntimeLineBox,
|
|
29
31
|
RuntimeNoteAllocation,
|
|
32
|
+
RuntimePageFrame,
|
|
30
33
|
RuntimePageGraph,
|
|
31
34
|
RuntimePageNode,
|
|
32
35
|
RuntimePageRegion,
|
|
33
36
|
RuntimePageRegions,
|
|
37
|
+
RuntimeTwipsRect,
|
|
34
38
|
} from "./page-graph.ts";
|
|
35
39
|
import type {
|
|
36
40
|
ResolvedFormattingState,
|
|
@@ -132,6 +136,40 @@ export function emitLayoutGuardWarning(
|
|
|
132
136
|
// Public read model types (shape-stable, cloned at the facet boundary)
|
|
133
137
|
// ---------------------------------------------------------------------------
|
|
134
138
|
|
|
139
|
+
export interface PublicTwipsRect {
|
|
140
|
+
xTwips: number;
|
|
141
|
+
yTwips: number;
|
|
142
|
+
widthTwips: number;
|
|
143
|
+
heightTwips: number;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export interface PublicLayoutDivergence {
|
|
147
|
+
divergenceId: string;
|
|
148
|
+
kind: RuntimeLayoutDivergence["kind"];
|
|
149
|
+
source: RuntimeLayoutDivergence["source"];
|
|
150
|
+
severity: RuntimeLayoutDivergence["severity"];
|
|
151
|
+
message: string;
|
|
152
|
+
regionKinds?: readonly RuntimePageRegion["kind"][];
|
|
153
|
+
fragmentIds?: readonly string[];
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export interface PublicPageFrame {
|
|
157
|
+
frameId: string;
|
|
158
|
+
pageId: string;
|
|
159
|
+
pageIndex: number;
|
|
160
|
+
sectionIndex: number;
|
|
161
|
+
displayPageNumber: number;
|
|
162
|
+
physicalBoundsTwips: PublicTwipsRect;
|
|
163
|
+
divergenceIds: readonly string[];
|
|
164
|
+
signature: string;
|
|
165
|
+
exclusionZoneCount: number;
|
|
166
|
+
regionFrames: readonly {
|
|
167
|
+
kind: RuntimePageRegion["kind"];
|
|
168
|
+
rectTwips?: PublicTwipsRect;
|
|
169
|
+
fragmentIds: readonly string[];
|
|
170
|
+
}[];
|
|
171
|
+
}
|
|
172
|
+
|
|
135
173
|
export interface PublicPageNode {
|
|
136
174
|
pageId: string;
|
|
137
175
|
pageIndex: number;
|
|
@@ -157,6 +195,10 @@ export interface PublicPageNode {
|
|
|
157
195
|
lineBoxCount: number;
|
|
158
196
|
/** Footnotes reserved at the bottom of the page, if any. */
|
|
159
197
|
noteAllocations: readonly PublicNoteAllocation[];
|
|
198
|
+
/** PE2 page-frame graph projection, when emitted by the L04 graph. */
|
|
199
|
+
frame?: PublicPageFrame;
|
|
200
|
+
/** Typed layout divergences detected while building this page. */
|
|
201
|
+
divergences?: readonly PublicLayoutDivergence[];
|
|
160
202
|
}
|
|
161
203
|
|
|
162
204
|
export interface PublicResolvedPageStories {
|
|
@@ -187,6 +229,8 @@ export interface PublicPageRegion {
|
|
|
187
229
|
widthTwips: number;
|
|
188
230
|
heightTwips: number;
|
|
189
231
|
fragmentCount: number;
|
|
232
|
+
/** PE2 semantic twips rect, when populated by the L04 page-frame graph. */
|
|
233
|
+
rectTwips?: PublicTwipsRect;
|
|
190
234
|
}
|
|
191
235
|
|
|
192
236
|
/**
|
|
@@ -208,8 +252,23 @@ export interface PublicBlockFragment {
|
|
|
208
252
|
to: number;
|
|
209
253
|
heightTwips: number;
|
|
210
254
|
orderInRegion: number;
|
|
255
|
+
kind?: "whole" | "paragraph-slice" | "table-slice";
|
|
256
|
+
paragraphLineRange?: {
|
|
257
|
+
from: number;
|
|
258
|
+
to: number;
|
|
259
|
+
totalLines: number;
|
|
260
|
+
};
|
|
261
|
+
tableRowRange?: {
|
|
262
|
+
from: number;
|
|
263
|
+
to: number;
|
|
264
|
+
totalRows: number;
|
|
265
|
+
};
|
|
266
|
+
columnIndex?: number;
|
|
267
|
+
continuation?: PublicLayoutContinuationCursor;
|
|
211
268
|
}
|
|
212
269
|
|
|
270
|
+
export type PublicLayoutContinuationCursor = RuntimeLayoutContinuationCursor;
|
|
271
|
+
|
|
213
272
|
/**
|
|
214
273
|
* P8 — One block snapshot rendered into a region of a page. Returned by
|
|
215
274
|
* `WordReviewEditorLayoutFacet.getStoryBlocksForRegion` and
|
|
@@ -245,6 +304,7 @@ export interface PublicNoteAllocation {
|
|
|
245
304
|
noteKind: "footnote" | "endnote";
|
|
246
305
|
noteId: string;
|
|
247
306
|
reservedHeightTwips: number;
|
|
307
|
+
fragmentId?: string;
|
|
248
308
|
}
|
|
249
309
|
|
|
250
310
|
export interface PublicPageAnchor {
|
|
@@ -1367,12 +1427,74 @@ function toPublicPageNode(
|
|
|
1367
1427
|
regions: toPublicPageRegions(node.regions),
|
|
1368
1428
|
lineBoxCount: node.lineBoxes.length,
|
|
1369
1429
|
noteAllocations: node.noteAllocations.map(toPublicNoteAllocation),
|
|
1430
|
+
...(node.frame ? { frame: toPublicPageFrame(node.frame) } : {}),
|
|
1431
|
+
...(node.divergences && node.divergences.length > 0
|
|
1432
|
+
? { divergences: node.divergences.map(toPublicLayoutDivergence) }
|
|
1433
|
+
: {}),
|
|
1370
1434
|
};
|
|
1371
1435
|
publicPageNodeCache.set(node, built);
|
|
1372
1436
|
void graph; // reserved for future cross-page derivations
|
|
1373
1437
|
return built;
|
|
1374
1438
|
}
|
|
1375
1439
|
|
|
1440
|
+
function toPublicTwipsRect(rect: RuntimeTwipsRect): PublicTwipsRect {
|
|
1441
|
+
return {
|
|
1442
|
+
xTwips: rect.xTwips,
|
|
1443
|
+
yTwips: rect.yTwips,
|
|
1444
|
+
widthTwips: rect.widthTwips,
|
|
1445
|
+
heightTwips: rect.heightTwips,
|
|
1446
|
+
};
|
|
1447
|
+
}
|
|
1448
|
+
|
|
1449
|
+
function frameRegionEntries(
|
|
1450
|
+
frame: RuntimePageFrame,
|
|
1451
|
+
): PublicPageFrame["regionFrames"] {
|
|
1452
|
+
const regions: PublicPageFrame["regionFrames"][number][] = [];
|
|
1453
|
+
const push = (region: RuntimePageRegion | undefined) => {
|
|
1454
|
+
if (!region) return;
|
|
1455
|
+
regions.push({
|
|
1456
|
+
kind: region.kind,
|
|
1457
|
+
...(region.rectTwips ? { rectTwips: toPublicTwipsRect(region.rectTwips) } : {}),
|
|
1458
|
+
fragmentIds: [...region.fragmentIds],
|
|
1459
|
+
});
|
|
1460
|
+
};
|
|
1461
|
+
push(frame.regions.header);
|
|
1462
|
+
push(frame.regions.body);
|
|
1463
|
+
for (const column of frame.regions.columns ?? []) push(column);
|
|
1464
|
+
push(frame.regions.footer);
|
|
1465
|
+
for (const footnote of frame.regions.footnotes ?? []) push(footnote);
|
|
1466
|
+
return regions;
|
|
1467
|
+
}
|
|
1468
|
+
|
|
1469
|
+
function toPublicPageFrame(frame: RuntimePageFrame): PublicPageFrame {
|
|
1470
|
+
return {
|
|
1471
|
+
frameId: frame.frameId,
|
|
1472
|
+
pageId: frame.pageId,
|
|
1473
|
+
pageIndex: frame.pageIndex,
|
|
1474
|
+
sectionIndex: frame.sectionIndex,
|
|
1475
|
+
displayPageNumber: frame.displayPageNumber,
|
|
1476
|
+
physicalBoundsTwips: toPublicTwipsRect(frame.physicalBoundsTwips),
|
|
1477
|
+
divergenceIds: [...frame.divergenceIds],
|
|
1478
|
+
signature: frame.signature,
|
|
1479
|
+
exclusionZoneCount: frame.regions.exclusionZones.length,
|
|
1480
|
+
regionFrames: frameRegionEntries(frame),
|
|
1481
|
+
};
|
|
1482
|
+
}
|
|
1483
|
+
|
|
1484
|
+
function toPublicLayoutDivergence(
|
|
1485
|
+
divergence: RuntimeLayoutDivergence,
|
|
1486
|
+
): PublicLayoutDivergence {
|
|
1487
|
+
return {
|
|
1488
|
+
divergenceId: divergence.divergenceId,
|
|
1489
|
+
kind: divergence.kind,
|
|
1490
|
+
source: divergence.source,
|
|
1491
|
+
severity: divergence.severity,
|
|
1492
|
+
message: divergence.message,
|
|
1493
|
+
...(divergence.regionKinds !== undefined ? { regionKinds: [...divergence.regionKinds] } : {}),
|
|
1494
|
+
...(divergence.fragmentIds !== undefined ? { fragmentIds: [...divergence.fragmentIds] } : {}),
|
|
1495
|
+
};
|
|
1496
|
+
}
|
|
1497
|
+
|
|
1376
1498
|
function toPublicResolvedPageStories(
|
|
1377
1499
|
stories: ResolvedPageStories,
|
|
1378
1500
|
): PublicResolvedPageStories {
|
|
@@ -1404,6 +1526,7 @@ function toPublicPageRegion(region: RuntimePageRegion): PublicPageRegion {
|
|
|
1404
1526
|
widthTwips: region.widthTwips,
|
|
1405
1527
|
heightTwips: region.heightTwips,
|
|
1406
1528
|
fragmentCount: region.fragmentIds.length,
|
|
1529
|
+
...(region.rectTwips ? { rectTwips: toPublicTwipsRect(region.rectTwips) } : {}),
|
|
1407
1530
|
};
|
|
1408
1531
|
}
|
|
1409
1532
|
|
|
@@ -1422,6 +1545,34 @@ function toPublicBlockFragment(
|
|
|
1422
1545
|
to: fragment.to,
|
|
1423
1546
|
heightTwips: fragment.heightTwips,
|
|
1424
1547
|
orderInRegion: fragment.orderInRegion,
|
|
1548
|
+
...(fragment.kind !== undefined ? { kind: fragment.kind } : {}),
|
|
1549
|
+
...(fragment.paragraphLineRange !== undefined
|
|
1550
|
+
? { paragraphLineRange: { ...fragment.paragraphLineRange } }
|
|
1551
|
+
: {}),
|
|
1552
|
+
...(fragment.tableRowRange !== undefined
|
|
1553
|
+
? { tableRowRange: { ...fragment.tableRowRange } }
|
|
1554
|
+
: {}),
|
|
1555
|
+
...(fragment.columnIndex !== undefined ? { columnIndex: fragment.columnIndex } : {}),
|
|
1556
|
+
...(fragment.continuation !== undefined
|
|
1557
|
+
? { continuation: cloneContinuationCursor(fragment.continuation) }
|
|
1558
|
+
: {}),
|
|
1559
|
+
};
|
|
1560
|
+
}
|
|
1561
|
+
|
|
1562
|
+
function cloneContinuationCursor(
|
|
1563
|
+
cursor: RuntimeLayoutContinuationCursor,
|
|
1564
|
+
): RuntimeLayoutContinuationCursor {
|
|
1565
|
+
if (cursor.kind === "paragraph") {
|
|
1566
|
+
return {
|
|
1567
|
+
...cursor,
|
|
1568
|
+
lineRange: { ...cursor.lineRange },
|
|
1569
|
+
};
|
|
1570
|
+
}
|
|
1571
|
+
return {
|
|
1572
|
+
...cursor,
|
|
1573
|
+
rowRange: { ...cursor.rowRange },
|
|
1574
|
+
repeatedHeaderRowIndexes: [...cursor.repeatedHeaderRowIndexes],
|
|
1575
|
+
verticalMergeCarry: cursor.verticalMergeCarry.map((carry) => ({ ...carry })),
|
|
1425
1576
|
};
|
|
1426
1577
|
}
|
|
1427
1578
|
|
|
@@ -1440,6 +1591,7 @@ function toPublicNoteAllocation(note: RuntimeNoteAllocation): PublicNoteAllocati
|
|
|
1440
1591
|
noteKind: note.noteKind,
|
|
1441
1592
|
noteId: note.noteId,
|
|
1442
1593
|
reservedHeightTwips: note.reservedHeightTwips,
|
|
1594
|
+
...(note.fragmentId !== undefined ? { fragmentId: note.fragmentId } : {}),
|
|
1443
1595
|
};
|
|
1444
1596
|
}
|
|
1445
1597
|
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
RuntimeBlockFragment,
|
|
3
3
|
RuntimePageAnchor,
|
|
4
|
+
RuntimePageFrame,
|
|
4
5
|
RuntimePageGraph,
|
|
6
|
+
RuntimePageLocalStoryInstance,
|
|
5
7
|
RuntimePageNode,
|
|
6
8
|
RuntimePageRegion,
|
|
7
9
|
RuntimePageRegions,
|
|
@@ -54,6 +56,9 @@ export function canonicalizeGraph(graph: RuntimePageGraph): RuntimePageGraph {
|
|
|
54
56
|
...page,
|
|
55
57
|
pageId: rewriteId(page.pageId),
|
|
56
58
|
regions: rewriteRegions(page.regions, rewriteId),
|
|
59
|
+
...(page.frame === undefined
|
|
60
|
+
? {}
|
|
61
|
+
: { frame: rewriteFrame(page.frame, rewriteId) }),
|
|
57
62
|
lineBoxes: page.lineBoxes.map((line) => ({
|
|
58
63
|
...line,
|
|
59
64
|
fragmentId: rewriteId(line.fragmentId),
|
|
@@ -86,6 +91,45 @@ export function canonicalizeGraph(graph: RuntimePageGraph): RuntimePageGraph {
|
|
|
86
91
|
};
|
|
87
92
|
}
|
|
88
93
|
|
|
94
|
+
function rewriteFrame(
|
|
95
|
+
frame: RuntimePageFrame,
|
|
96
|
+
rewriteId: (id: string) => string,
|
|
97
|
+
): RuntimePageFrame {
|
|
98
|
+
return {
|
|
99
|
+
...frame,
|
|
100
|
+
pageId: rewriteId(frame.pageId),
|
|
101
|
+
pageLocalStories: frame.pageLocalStories.map((story) =>
|
|
102
|
+
rewritePageLocalStoryInstance(story, rewriteId),
|
|
103
|
+
),
|
|
104
|
+
regions: {
|
|
105
|
+
...frame.regions,
|
|
106
|
+
body: rewriteRegion(frame.regions.body, rewriteId),
|
|
107
|
+
...(frame.regions.header
|
|
108
|
+
? { header: rewriteRegion(frame.regions.header, rewriteId) }
|
|
109
|
+
: {}),
|
|
110
|
+
...(frame.regions.footer
|
|
111
|
+
? { footer: rewriteRegion(frame.regions.footer, rewriteId) }
|
|
112
|
+
: {}),
|
|
113
|
+
...(frame.regions.columns
|
|
114
|
+
? { columns: frame.regions.columns.map((region) => rewriteRegion(region, rewriteId)) }
|
|
115
|
+
: {}),
|
|
116
|
+
...(frame.regions.footnotes
|
|
117
|
+
? { footnotes: frame.regions.footnotes.map((region) => rewriteRegion(region, rewriteId)) }
|
|
118
|
+
: {}),
|
|
119
|
+
},
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function rewritePageLocalStoryInstance(
|
|
124
|
+
story: RuntimePageLocalStoryInstance,
|
|
125
|
+
rewriteId: (id: string) => string,
|
|
126
|
+
): RuntimePageLocalStoryInstance {
|
|
127
|
+
return {
|
|
128
|
+
...story,
|
|
129
|
+
pageId: rewriteId(story.pageId),
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
|
|
89
133
|
function rewriteRegions(
|
|
90
134
|
regions: RuntimePageRegions,
|
|
91
135
|
rewriteId: (id: string) => string,
|
|
@@ -6,6 +6,7 @@ import type {
|
|
|
6
6
|
SurfaceDrawingAnchor,
|
|
7
7
|
SurfaceInlineSegment,
|
|
8
8
|
SurfacePictureEffects,
|
|
9
|
+
SurfacePreserveOnlyObjectSizing,
|
|
9
10
|
SurfaceTableCellSnapshot,
|
|
10
11
|
SurfaceTableRowSnapshot,
|
|
11
12
|
SurfaceTextMark,
|
|
@@ -38,6 +39,7 @@ import type {
|
|
|
38
39
|
TextMark,
|
|
39
40
|
DrawingFrameNode,
|
|
40
41
|
PictureContent,
|
|
42
|
+
PreserveOnlyObjectSizing,
|
|
41
43
|
ShapeContent,
|
|
42
44
|
VmlShapeNode,
|
|
43
45
|
WordArtNode,
|
|
@@ -1549,6 +1551,9 @@ function appendInlineSegments(
|
|
|
1549
1551
|
...(c.line ? { line: c.line } : {}),
|
|
1550
1552
|
...(c.isTextBox ? { isTextBox: true } : {}),
|
|
1551
1553
|
...(c.textBoxBody ? { textBoxBody: c.textBoxBody } : {}),
|
|
1554
|
+
...(c.preserveOnlyObject
|
|
1555
|
+
? { preserveOnlyObject: surfacePreserveOnlyObject(c.preserveOnlyObject) }
|
|
1556
|
+
: {}),
|
|
1552
1557
|
...(txbxText ? { txbxText } : {}),
|
|
1553
1558
|
...(txbxTextSegment?.marks && txbxTextSegment.marks.length > 0
|
|
1554
1559
|
? { txbxMarks: txbxTextSegment.marks }
|
|
@@ -1568,6 +1573,7 @@ function appendInlineSegments(
|
|
|
1568
1573
|
{
|
|
1569
1574
|
previewMediaId: c.previewMediaId,
|
|
1570
1575
|
parsedChartId,
|
|
1576
|
+
anchor: surfaceAnchorFromGeometry(node.anchor),
|
|
1571
1577
|
},
|
|
1572
1578
|
);
|
|
1573
1579
|
}
|
|
@@ -1578,7 +1584,10 @@ function appendInlineSegments(
|
|
|
1578
1584
|
start,
|
|
1579
1585
|
"SmartArt diagram",
|
|
1580
1586
|
`DrawingFrame smartart_preview (${node.anchor.wrapMode}).`,
|
|
1581
|
-
{
|
|
1587
|
+
{
|
|
1588
|
+
previewMediaId: c.previewMediaId,
|
|
1589
|
+
anchor: surfaceAnchorFromGeometry(node.anchor),
|
|
1590
|
+
},
|
|
1582
1591
|
);
|
|
1583
1592
|
}
|
|
1584
1593
|
return appendComplexPreviewSegment(
|
|
@@ -1587,6 +1596,7 @@ function appendInlineSegments(
|
|
|
1587
1596
|
start,
|
|
1588
1597
|
"Drawing frame",
|
|
1589
1598
|
`DrawingFrame ${c.type} (${node.anchor.wrapMode}).`,
|
|
1599
|
+
{ anchor: surfaceAnchorFromGeometry(node.anchor) },
|
|
1590
1600
|
);
|
|
1591
1601
|
}
|
|
1592
1602
|
case "symbol":
|
|
@@ -2109,12 +2119,19 @@ function extractTxbxFirstTextSegment(
|
|
|
2109
2119
|
|
|
2110
2120
|
function appendComplexPreviewSegment(
|
|
2111
2121
|
paragraph: ParagraphAccumulator,
|
|
2112
|
-
node: { rawXml: string },
|
|
2122
|
+
node: { rawXml: string; preserveOnlyObject?: PreserveOnlyObjectSizing },
|
|
2113
2123
|
start: number,
|
|
2114
2124
|
label: string,
|
|
2115
2125
|
detail: string,
|
|
2116
|
-
extras: {
|
|
2126
|
+
extras: {
|
|
2127
|
+
previewMediaId?: string;
|
|
2128
|
+
parsedChartId?: string;
|
|
2129
|
+
anchor?: SurfaceDrawingAnchor;
|
|
2130
|
+
} = {},
|
|
2117
2131
|
): { nextCursor: number; lockedFragmentIds: string[] } {
|
|
2132
|
+
const preserveOnlyObject = node.preserveOnlyObject
|
|
2133
|
+
? surfacePreserveOnlyObject(node.preserveOnlyObject)
|
|
2134
|
+
: undefined;
|
|
2118
2135
|
paragraph.segments.push({
|
|
2119
2136
|
segmentId: `${paragraph.blockId}-segment-${paragraph.segments.length}`,
|
|
2120
2137
|
kind: "opaque_inline",
|
|
@@ -2126,11 +2143,34 @@ function appendComplexPreviewSegment(
|
|
|
2126
2143
|
detail,
|
|
2127
2144
|
...(extras.previewMediaId ? { previewMediaId: extras.previewMediaId } : {}),
|
|
2128
2145
|
...(extras.parsedChartId ? { parsedChartId: extras.parsedChartId } : {}),
|
|
2146
|
+
...(preserveOnlyObject ? { preserveOnlyObject } : {}),
|
|
2147
|
+
...(extras.anchor ? { anchor: extras.anchor } : {}),
|
|
2129
2148
|
state: "locked-preserve-only",
|
|
2130
2149
|
});
|
|
2131
2150
|
return { nextCursor: start + 1, lockedFragmentIds: [] };
|
|
2132
2151
|
}
|
|
2133
2152
|
|
|
2153
|
+
function surfacePreserveOnlyObject(
|
|
2154
|
+
object: PreserveOnlyObjectSizing,
|
|
2155
|
+
): SurfacePreserveOnlyObjectSizing {
|
|
2156
|
+
return {
|
|
2157
|
+
...(object.sourceId ? { sourceId: object.sourceId } : {}),
|
|
2158
|
+
display: object.display,
|
|
2159
|
+
...(object.extentEmu
|
|
2160
|
+
? {
|
|
2161
|
+
extentEmu: {
|
|
2162
|
+
widthEmu: object.extentEmu.widthEmu,
|
|
2163
|
+
heightEmu: object.extentEmu.heightEmu,
|
|
2164
|
+
},
|
|
2165
|
+
}
|
|
2166
|
+
: {}),
|
|
2167
|
+
fallbackHint: object.fallbackHint,
|
|
2168
|
+
...(object.relationshipIds && object.relationshipIds.length > 0
|
|
2169
|
+
? { relationshipIds: [...object.relationshipIds] }
|
|
2170
|
+
: {}),
|
|
2171
|
+
};
|
|
2172
|
+
}
|
|
2173
|
+
|
|
2134
2174
|
function appendTextBoxSegment(
|
|
2135
2175
|
paragraph: ParagraphAccumulator,
|
|
2136
2176
|
start: number,
|