@extend-ai/react-docx 0.7.0-alpha.1 → 0.7.0-alpha.3
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/README.md +28 -0
- package/dist/chunk-BGCGPO6Q.js +575 -0
- package/dist/chunk-BGCGPO6Q.js.map +1 -0
- package/dist/docx_wasm_bg.wasm +0 -0
- package/dist/index.cjs +1034 -453
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +28 -1
- package/dist/index.d.ts +28 -1
- package/dist/index.js +859 -375
- package/dist/index.js.map +1 -1
- package/dist/{src-JDYUD5TO.js → src-XA2NEWYM.js} +2 -2
- package/package.json +4 -2
- package/dist/chunk-AWFSO3IU.js +0 -505
- package/dist/chunk-AWFSO3IU.js.map +0 -1
- /package/dist/{src-JDYUD5TO.js.map → src-XA2NEWYM.js.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createMinimalDocxPackage,
|
|
3
3
|
getPart,
|
|
4
|
+
initWasm,
|
|
4
5
|
mapsToWasmPackage,
|
|
5
6
|
packageToArrayBuffer,
|
|
6
7
|
parseDocx,
|
|
8
|
+
setWasmSource,
|
|
7
9
|
wasmBuildDocModelFromPackage,
|
|
8
10
|
wasmModelToDocumentXml,
|
|
9
11
|
wasmSerializeDocx,
|
|
10
12
|
withPart
|
|
11
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-BGCGPO6Q.js";
|
|
12
14
|
|
|
13
15
|
// src/index.tsx
|
|
14
16
|
import * as React2 from "react";
|
|
@@ -636,7 +638,7 @@ async function buildDocModel(pkg) {
|
|
|
636
638
|
return normalizeDocModel(model);
|
|
637
639
|
}
|
|
638
640
|
async function buildDocModelFromBytes(bytes) {
|
|
639
|
-
const { parseDocx: parseDocx2 } = await import("./src-
|
|
641
|
+
const { parseDocx: parseDocx2 } = await import("./src-XA2NEWYM.js");
|
|
640
642
|
const payload = bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes);
|
|
641
643
|
const buffer = payload.buffer.slice(payload.byteOffset, payload.byteOffset + payload.byteLength);
|
|
642
644
|
const pkg = await parseDocx2(buffer);
|
|
@@ -2007,7 +2009,7 @@ async function serializeDocModel(model, basePackage) {
|
|
|
2007
2009
|
model,
|
|
2008
2010
|
basePackage ? mapsToWasmPackage(basePackage) : void 0
|
|
2009
2011
|
);
|
|
2010
|
-
const { parseDocx: parseDocx2 } = await import("./src-
|
|
2012
|
+
const { parseDocx: parseDocx2 } = await import("./src-XA2NEWYM.js");
|
|
2011
2013
|
return parseDocx2(bytes);
|
|
2012
2014
|
}
|
|
2013
2015
|
async function serializeDocx(model, basePackage) {
|
|
@@ -2176,16 +2178,17 @@ function shouldAllowStoredPageCountReduction(options) {
|
|
|
2176
2178
|
if (targetPageCount >= estimatedPageCount) {
|
|
2177
2179
|
return true;
|
|
2178
2180
|
}
|
|
2181
|
+
const renderedBreakHintPageCount = Number.isFinite(
|
|
2182
|
+
options.renderedBreakHintPageCount
|
|
2183
|
+
) ? Math.max(1, Math.round(options.renderedBreakHintPageCount)) : void 0;
|
|
2184
|
+
const renderedBreakHintsSupportTarget = options.hasLastRenderedPageBreakHints === true && renderedBreakHintPageCount !== void 0 && targetPageCount >= renderedBreakHintPageCount;
|
|
2179
2185
|
if (options.hasMeasuredBodyFooterOverlap === true) {
|
|
2180
|
-
return
|
|
2186
|
+
return renderedBreakHintsSupportTarget;
|
|
2181
2187
|
}
|
|
2182
2188
|
if (options.hasLastRenderedPageBreakHints !== true) {
|
|
2183
2189
|
return true;
|
|
2184
2190
|
}
|
|
2185
|
-
|
|
2186
|
-
options.renderedBreakHintPageCount
|
|
2187
|
-
) ? Math.max(1, Math.round(options.renderedBreakHintPageCount)) : void 0;
|
|
2188
|
-
return renderedBreakHintPageCount !== void 0 && targetPageCount >= renderedBreakHintPageCount;
|
|
2191
|
+
return renderedBreakHintsSupportTarget;
|
|
2189
2192
|
}
|
|
2190
2193
|
function shouldLatchMeasuredBodyFooterOverlap(options) {
|
|
2191
2194
|
if (options.measuredBodyFooterOverlap !== true) {
|
|
@@ -3295,6 +3298,423 @@ function sliceLayoutToLineRange(layout, startLineIndex, endLineIndex) {
|
|
|
3295
3298
|
};
|
|
3296
3299
|
}
|
|
3297
3300
|
|
|
3301
|
+
// src/content-signature.ts
|
|
3302
|
+
var FNV_OFFSET_BASIS = 2166136261;
|
|
3303
|
+
var FNV_PRIME = 16777619;
|
|
3304
|
+
var LONG_STRING_SAMPLE_LENGTH = 64;
|
|
3305
|
+
var LONG_STRING_THRESHOLD = 256;
|
|
3306
|
+
function fnv1aAppend(hash, text) {
|
|
3307
|
+
let next = hash;
|
|
3308
|
+
for (let index = 0; index < text.length; index += 1) {
|
|
3309
|
+
next ^= text.charCodeAt(index);
|
|
3310
|
+
next = Math.imul(next, FNV_PRIME);
|
|
3311
|
+
}
|
|
3312
|
+
return next >>> 0;
|
|
3313
|
+
}
|
|
3314
|
+
function fnv1aAppendString(hash, value) {
|
|
3315
|
+
if (value.length <= LONG_STRING_THRESHOLD) {
|
|
3316
|
+
return fnv1aAppend(fnv1aAppend(hash, `${value.length}:`), value);
|
|
3317
|
+
}
|
|
3318
|
+
const head = value.slice(0, LONG_STRING_SAMPLE_LENGTH);
|
|
3319
|
+
const middleIndex = Math.floor(value.length / 2);
|
|
3320
|
+
const middle = value.slice(
|
|
3321
|
+
middleIndex,
|
|
3322
|
+
middleIndex + LONG_STRING_SAMPLE_LENGTH
|
|
3323
|
+
);
|
|
3324
|
+
const tail = value.slice(value.length - LONG_STRING_SAMPLE_LENGTH);
|
|
3325
|
+
let next = fnv1aAppend(hash, `${value.length}:`);
|
|
3326
|
+
next = fnv1aAppend(next, head);
|
|
3327
|
+
next = fnv1aAppend(next, middle);
|
|
3328
|
+
return fnv1aAppend(next, tail);
|
|
3329
|
+
}
|
|
3330
|
+
function fnv1aAppendValue(hash, value) {
|
|
3331
|
+
if (value === null) {
|
|
3332
|
+
return fnv1aAppend(hash, "~n");
|
|
3333
|
+
}
|
|
3334
|
+
switch (typeof value) {
|
|
3335
|
+
case "undefined":
|
|
3336
|
+
return fnv1aAppend(hash, "~u");
|
|
3337
|
+
case "string":
|
|
3338
|
+
return fnv1aAppendString(fnv1aAppend(hash, "~s"), value);
|
|
3339
|
+
case "number":
|
|
3340
|
+
return fnv1aAppend(hash, `~#${value}`);
|
|
3341
|
+
case "boolean":
|
|
3342
|
+
return fnv1aAppend(hash, value ? "~t" : "~f");
|
|
3343
|
+
case "object":
|
|
3344
|
+
break;
|
|
3345
|
+
default:
|
|
3346
|
+
return fnv1aAppend(hash, "~x");
|
|
3347
|
+
}
|
|
3348
|
+
if (Array.isArray(value)) {
|
|
3349
|
+
let next2 = fnv1aAppend(hash, `~a${value.length}`);
|
|
3350
|
+
for (const entry of value) {
|
|
3351
|
+
next2 = fnv1aAppendValue(next2, entry);
|
|
3352
|
+
}
|
|
3353
|
+
return next2;
|
|
3354
|
+
}
|
|
3355
|
+
if (ArrayBuffer.isView(value) || value instanceof ArrayBuffer) {
|
|
3356
|
+
const byteLength = value instanceof ArrayBuffer ? value.byteLength : value.byteLength;
|
|
3357
|
+
return fnv1aAppend(hash, `~b${byteLength}`);
|
|
3358
|
+
}
|
|
3359
|
+
let next = fnv1aAppend(hash, "~o");
|
|
3360
|
+
for (const key of Object.keys(value)) {
|
|
3361
|
+
const entry = value[key];
|
|
3362
|
+
if (entry === void 0) {
|
|
3363
|
+
continue;
|
|
3364
|
+
}
|
|
3365
|
+
next = fnv1aAppend(next, key);
|
|
3366
|
+
next = fnv1aAppendValue(next, entry);
|
|
3367
|
+
}
|
|
3368
|
+
return next;
|
|
3369
|
+
}
|
|
3370
|
+
function contentHash(value) {
|
|
3371
|
+
return fnv1aAppendValue(FNV_OFFSET_BASIS, value).toString(36);
|
|
3372
|
+
}
|
|
3373
|
+
var nodeSignatureCache = /* @__PURE__ */ new WeakMap();
|
|
3374
|
+
function docNodeContentSignature(node) {
|
|
3375
|
+
if (typeof node !== "object" || node === null) {
|
|
3376
|
+
return contentHash(node);
|
|
3377
|
+
}
|
|
3378
|
+
const cached = nodeSignatureCache.get(node);
|
|
3379
|
+
if (cached !== void 0) {
|
|
3380
|
+
return cached;
|
|
3381
|
+
}
|
|
3382
|
+
const signature = contentHash(node);
|
|
3383
|
+
nodeSignatureCache.set(node, signature);
|
|
3384
|
+
return signature;
|
|
3385
|
+
}
|
|
3386
|
+
var metadataSignatureCache = /* @__PURE__ */ new WeakMap();
|
|
3387
|
+
function docModelThumbnailMetadataSignature(metadata) {
|
|
3388
|
+
const cached = metadataSignatureCache.get(metadata);
|
|
3389
|
+
if (cached !== void 0) {
|
|
3390
|
+
return cached;
|
|
3391
|
+
}
|
|
3392
|
+
const relevant = metadata;
|
|
3393
|
+
let hash = FNV_OFFSET_BASIS;
|
|
3394
|
+
hash = fnv1aAppendValue(hash, relevant.sections);
|
|
3395
|
+
hash = fnv1aAppendValue(hash, relevant.headerSections);
|
|
3396
|
+
hash = fnv1aAppendValue(hash, relevant.footerSections);
|
|
3397
|
+
hash = fnv1aAppendValue(hash, relevant.numberingDefinitions);
|
|
3398
|
+
hash = fnv1aAppendValue(hash, relevant.footnotes);
|
|
3399
|
+
hash = fnv1aAppendValue(hash, relevant.endnotes);
|
|
3400
|
+
hash = fnv1aAppendValue(hash, relevant.documentBackgroundColor);
|
|
3401
|
+
hash = fnv1aAppendValue(hash, relevant.compatibility);
|
|
3402
|
+
const signature = (hash >>> 0).toString(36);
|
|
3403
|
+
metadataSignatureCache.set(metadata, signature);
|
|
3404
|
+
return signature;
|
|
3405
|
+
}
|
|
3406
|
+
|
|
3407
|
+
// src/thumbnail-raster.ts
|
|
3408
|
+
var DOCX_THUMBNAIL_EXCLUDE_ATTRIBUTE = "data-docx-thumbnail-exclude";
|
|
3409
|
+
var THUMBNAIL_EXCLUDED_CLONE_SELECTOR = [
|
|
3410
|
+
`[${DOCX_THUMBNAIL_EXCLUDE_ATTRIBUTE}="true"]`,
|
|
3411
|
+
"textarea",
|
|
3412
|
+
'[data-image-resize-handle="true"]',
|
|
3413
|
+
'[data-docx-table-move-handle="true"]'
|
|
3414
|
+
].join(",");
|
|
3415
|
+
var THUMBNAIL_IMAGE_DOWNSCALE_MIN_DATA_URI_LENGTH = 32768;
|
|
3416
|
+
var THUMBNAIL_IMAGE_DOWNSCALE_MAX_DIMENSION_PX = 512;
|
|
3417
|
+
var THUMBNAIL_IMAGE_JPEG_QUALITY = 0.78;
|
|
3418
|
+
function thumbnailSvgDataUri(svg) {
|
|
3419
|
+
return `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg)}`;
|
|
3420
|
+
}
|
|
3421
|
+
function thumbnailImageSourceQualifiesForDownscale(src) {
|
|
3422
|
+
return src.length >= THUMBNAIL_IMAGE_DOWNSCALE_MIN_DATA_URI_LENGTH && src.startsWith("data:image/") && !src.startsWith("data:image/svg");
|
|
3423
|
+
}
|
|
3424
|
+
async function loadThumbnailImage(src) {
|
|
3425
|
+
const image = new Image();
|
|
3426
|
+
image.decoding = "async";
|
|
3427
|
+
const loaded = new Promise((resolve, reject) => {
|
|
3428
|
+
image.onload = () => resolve(image);
|
|
3429
|
+
image.onerror = () => {
|
|
3430
|
+
reject(new Error("Failed to decode DOCX thumbnail image."));
|
|
3431
|
+
};
|
|
3432
|
+
});
|
|
3433
|
+
image.src = src;
|
|
3434
|
+
if (typeof image.decode === "function") {
|
|
3435
|
+
try {
|
|
3436
|
+
await image.decode();
|
|
3437
|
+
return image;
|
|
3438
|
+
} catch {
|
|
3439
|
+
}
|
|
3440
|
+
}
|
|
3441
|
+
return loaded;
|
|
3442
|
+
}
|
|
3443
|
+
var downscaledThumbnailImageCache = /* @__PURE__ */ new Map();
|
|
3444
|
+
async function downscaleThumbnailImageDataUri(src) {
|
|
3445
|
+
if (typeof document === "undefined") {
|
|
3446
|
+
return void 0;
|
|
3447
|
+
}
|
|
3448
|
+
const image = await loadThumbnailImage(src);
|
|
3449
|
+
const naturalWidth = image.naturalWidth || image.width;
|
|
3450
|
+
const naturalHeight = image.naturalHeight || image.height;
|
|
3451
|
+
if (!naturalWidth || !naturalHeight) {
|
|
3452
|
+
return void 0;
|
|
3453
|
+
}
|
|
3454
|
+
const scale = THUMBNAIL_IMAGE_DOWNSCALE_MAX_DIMENSION_PX / Math.max(naturalWidth, naturalHeight);
|
|
3455
|
+
if (scale >= 1) {
|
|
3456
|
+
return void 0;
|
|
3457
|
+
}
|
|
3458
|
+
const canvas = document.createElement("canvas");
|
|
3459
|
+
canvas.width = Math.max(1, Math.round(naturalWidth * scale));
|
|
3460
|
+
canvas.height = Math.max(1, Math.round(naturalHeight * scale));
|
|
3461
|
+
const context = canvas.getContext("2d");
|
|
3462
|
+
if (!context) {
|
|
3463
|
+
return void 0;
|
|
3464
|
+
}
|
|
3465
|
+
context.imageSmoothingEnabled = true;
|
|
3466
|
+
context.imageSmoothingQuality = "high";
|
|
3467
|
+
context.drawImage(image, 0, 0, canvas.width, canvas.height);
|
|
3468
|
+
const sourceIsJpeg = src.startsWith("data:image/jpeg") || src.startsWith("data:image/jpg");
|
|
3469
|
+
const downscaled = sourceIsJpeg ? canvas.toDataURL("image/jpeg", THUMBNAIL_IMAGE_JPEG_QUALITY) : canvas.toDataURL("image/png");
|
|
3470
|
+
return downscaled.length < src.length ? downscaled : void 0;
|
|
3471
|
+
}
|
|
3472
|
+
function getDownscaledThumbnailImageDataUri(src) {
|
|
3473
|
+
const cached = downscaledThumbnailImageCache.get(src);
|
|
3474
|
+
if (cached) {
|
|
3475
|
+
return cached;
|
|
3476
|
+
}
|
|
3477
|
+
const pending = downscaleThumbnailImageDataUri(src).catch(() => void 0);
|
|
3478
|
+
downscaledThumbnailImageCache.set(src, pending);
|
|
3479
|
+
return pending;
|
|
3480
|
+
}
|
|
3481
|
+
async function buildDocxThumbnailSvgMarkup(params) {
|
|
3482
|
+
const { pageElement, sourceWidthPx, sourceHeightPx, widthPx, heightPx } = params;
|
|
3483
|
+
const clone = pageElement.cloneNode(true);
|
|
3484
|
+
clone.querySelectorAll(THUMBNAIL_EXCLUDED_CLONE_SELECTOR).forEach((excluded) => {
|
|
3485
|
+
excluded.remove();
|
|
3486
|
+
});
|
|
3487
|
+
const cloneImages = Array.from(clone.querySelectorAll("img"));
|
|
3488
|
+
await Promise.all(
|
|
3489
|
+
cloneImages.map(async (cloneImage) => {
|
|
3490
|
+
const src = cloneImage.getAttribute("src");
|
|
3491
|
+
if (!src || !thumbnailImageSourceQualifiesForDownscale(src)) {
|
|
3492
|
+
return;
|
|
3493
|
+
}
|
|
3494
|
+
const downscaled = await getDownscaledThumbnailImageDataUri(src);
|
|
3495
|
+
if (downscaled) {
|
|
3496
|
+
cloneImage.setAttribute("src", downscaled);
|
|
3497
|
+
}
|
|
3498
|
+
})
|
|
3499
|
+
);
|
|
3500
|
+
const scaleX = widthPx / sourceWidthPx;
|
|
3501
|
+
const scaleY = heightPx / sourceHeightPx;
|
|
3502
|
+
const serializedPage = new XMLSerializer().serializeToString(clone);
|
|
3503
|
+
return `
|
|
3504
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="${widthPx}" height="${heightPx}" viewBox="0 0 ${widthPx} ${heightPx}">
|
|
3505
|
+
<foreignObject x="0" y="0" width="100%" height="100%">
|
|
3506
|
+
<div xmlns="http://www.w3.org/1999/xhtml" style="width:${widthPx}px;height:${heightPx}px;overflow:hidden;">
|
|
3507
|
+
<div style="width:${sourceWidthPx}px;height:${sourceHeightPx}px;transform-origin:top left;transform:scale(${scaleX}, ${scaleY});">
|
|
3508
|
+
${serializedPage}
|
|
3509
|
+
</div>
|
|
3510
|
+
</div>
|
|
3511
|
+
</foreignObject>
|
|
3512
|
+
</svg>
|
|
3513
|
+
`;
|
|
3514
|
+
}
|
|
3515
|
+
async function rasterizeDocxThumbnailSurface(params) {
|
|
3516
|
+
if (typeof window === "undefined" || typeof XMLSerializer === "undefined") {
|
|
3517
|
+
throw new Error("DOCX thumbnails require a browser environment.");
|
|
3518
|
+
}
|
|
3519
|
+
const safeSourceWidthPx = Math.max(1, Math.round(params.sourceWidthPx));
|
|
3520
|
+
const safeSourceHeightPx = Math.max(1, Math.round(params.sourceHeightPx));
|
|
3521
|
+
const svgMarkup = await buildDocxThumbnailSvgMarkup({
|
|
3522
|
+
pageElement: params.pageElement,
|
|
3523
|
+
sourceWidthPx: safeSourceWidthPx,
|
|
3524
|
+
sourceHeightPx: safeSourceHeightPx,
|
|
3525
|
+
widthPx: params.widthPx,
|
|
3526
|
+
heightPx: params.heightPx
|
|
3527
|
+
});
|
|
3528
|
+
const image = await loadThumbnailImage(thumbnailSvgDataUri(svgMarkup));
|
|
3529
|
+
const surface = document.createElement("canvas");
|
|
3530
|
+
surface.width = Math.max(1, Math.round(params.pixelWidthPx));
|
|
3531
|
+
surface.height = Math.max(1, Math.round(params.pixelHeightPx));
|
|
3532
|
+
const context = surface.getContext("2d");
|
|
3533
|
+
if (!context) {
|
|
3534
|
+
throw new Error("2D canvas context is unavailable for DOCX thumbnails.");
|
|
3535
|
+
}
|
|
3536
|
+
context.imageSmoothingEnabled = true;
|
|
3537
|
+
context.imageSmoothingQuality = "high";
|
|
3538
|
+
context.drawImage(image, 0, 0, surface.width, surface.height);
|
|
3539
|
+
return surface;
|
|
3540
|
+
}
|
|
3541
|
+
function blitDocxThumbnailSurface(surface, canvas, resolution) {
|
|
3542
|
+
canvas.width = Math.max(1, Math.round(resolution.pixelWidthPx));
|
|
3543
|
+
canvas.height = Math.max(1, Math.round(resolution.pixelHeightPx));
|
|
3544
|
+
canvas.style.width = `${Math.max(1, Math.round(resolution.widthPx))}px`;
|
|
3545
|
+
canvas.style.height = `${Math.max(1, Math.round(resolution.heightPx))}px`;
|
|
3546
|
+
const context = canvas.getContext("2d");
|
|
3547
|
+
if (!context) {
|
|
3548
|
+
throw new Error("2D canvas context is unavailable for DOCX thumbnails.");
|
|
3549
|
+
}
|
|
3550
|
+
context.setTransform(1, 0, 0, 1, 0, 0);
|
|
3551
|
+
context.clearRect(0, 0, canvas.width, canvas.height);
|
|
3552
|
+
context.drawImage(surface, 0, 0, canvas.width, canvas.height);
|
|
3553
|
+
}
|
|
3554
|
+
var DocxThumbnailSurfaceCache = class {
|
|
3555
|
+
constructor(maxEntries) {
|
|
3556
|
+
this.maxEntries = maxEntries;
|
|
3557
|
+
}
|
|
3558
|
+
entries = /* @__PURE__ */ new Map();
|
|
3559
|
+
get size() {
|
|
3560
|
+
return this.entries.size;
|
|
3561
|
+
}
|
|
3562
|
+
get(key) {
|
|
3563
|
+
const value = this.entries.get(key);
|
|
3564
|
+
if (value === void 0) {
|
|
3565
|
+
return void 0;
|
|
3566
|
+
}
|
|
3567
|
+
this.entries.delete(key);
|
|
3568
|
+
this.entries.set(key, value);
|
|
3569
|
+
return value;
|
|
3570
|
+
}
|
|
3571
|
+
set(key, value) {
|
|
3572
|
+
this.entries.delete(key);
|
|
3573
|
+
this.entries.set(key, value);
|
|
3574
|
+
while (this.entries.size > this.maxEntries) {
|
|
3575
|
+
const oldestKey = this.entries.keys().next().value;
|
|
3576
|
+
if (oldestKey === void 0) {
|
|
3577
|
+
break;
|
|
3578
|
+
}
|
|
3579
|
+
this.entries.delete(oldestKey);
|
|
3580
|
+
}
|
|
3581
|
+
}
|
|
3582
|
+
clear() {
|
|
3583
|
+
this.entries.clear();
|
|
3584
|
+
}
|
|
3585
|
+
};
|
|
3586
|
+
var IDLE_TASK_TIMEOUT_MS = 300;
|
|
3587
|
+
function defaultScheduleTask(callback) {
|
|
3588
|
+
const idleWindow = typeof window === "undefined" ? void 0 : window;
|
|
3589
|
+
if (!idleWindow || typeof idleWindow.requestIdleCallback !== "function") {
|
|
3590
|
+
setTimeout(callback, 16);
|
|
3591
|
+
return;
|
|
3592
|
+
}
|
|
3593
|
+
let invoked = false;
|
|
3594
|
+
const runOnce = () => {
|
|
3595
|
+
if (invoked) {
|
|
3596
|
+
return;
|
|
3597
|
+
}
|
|
3598
|
+
invoked = true;
|
|
3599
|
+
callback();
|
|
3600
|
+
};
|
|
3601
|
+
const idleHandle = idleWindow.requestIdleCallback(runOnce, {
|
|
3602
|
+
timeout: IDLE_TASK_TIMEOUT_MS
|
|
3603
|
+
});
|
|
3604
|
+
setTimeout(() => {
|
|
3605
|
+
if (invoked) {
|
|
3606
|
+
return;
|
|
3607
|
+
}
|
|
3608
|
+
if (typeof idleWindow.cancelIdleCallback === "function") {
|
|
3609
|
+
idleWindow.cancelIdleCallback(idleHandle);
|
|
3610
|
+
}
|
|
3611
|
+
runOnce();
|
|
3612
|
+
}, IDLE_TASK_TIMEOUT_MS + 50);
|
|
3613
|
+
}
|
|
3614
|
+
function defaultScheduleDelayed(callback, delayMs) {
|
|
3615
|
+
setTimeout(callback, delayMs);
|
|
3616
|
+
}
|
|
3617
|
+
var SerialIdleTaskQueue = class {
|
|
3618
|
+
pending = [];
|
|
3619
|
+
lastRunAtByKey = /* @__PURE__ */ new Map();
|
|
3620
|
+
scheduleTask;
|
|
3621
|
+
scheduleDelayed;
|
|
3622
|
+
minTaskIntervalMs;
|
|
3623
|
+
now;
|
|
3624
|
+
pumpScheduled = false;
|
|
3625
|
+
running = false;
|
|
3626
|
+
constructor(options) {
|
|
3627
|
+
this.scheduleTask = options?.scheduleTask ?? defaultScheduleTask;
|
|
3628
|
+
this.scheduleDelayed = options?.scheduleDelayed ?? defaultScheduleDelayed;
|
|
3629
|
+
this.minTaskIntervalMs = Math.max(0, options?.minTaskIntervalMs ?? 0);
|
|
3630
|
+
this.now = options?.now ?? (() => Date.now());
|
|
3631
|
+
}
|
|
3632
|
+
get pendingCount() {
|
|
3633
|
+
return this.pending.length;
|
|
3634
|
+
}
|
|
3635
|
+
enqueue(key, run) {
|
|
3636
|
+
return new Promise((resolve) => {
|
|
3637
|
+
const existing = this.pending.find((entry) => entry.key === key);
|
|
3638
|
+
if (existing) {
|
|
3639
|
+
existing.run = run;
|
|
3640
|
+
existing.resolvers.push(resolve);
|
|
3641
|
+
} else {
|
|
3642
|
+
this.pending.push({ key, run, resolvers: [resolve] });
|
|
3643
|
+
}
|
|
3644
|
+
this.schedulePump();
|
|
3645
|
+
});
|
|
3646
|
+
}
|
|
3647
|
+
/** Drops all queued tasks, resolving their waiters without running them. */
|
|
3648
|
+
clear() {
|
|
3649
|
+
const dropped = this.pending.splice(0, this.pending.length);
|
|
3650
|
+
this.lastRunAtByKey.clear();
|
|
3651
|
+
dropped.forEach((entry) => {
|
|
3652
|
+
entry.resolvers.forEach((resolveEntry) => {
|
|
3653
|
+
resolveEntry();
|
|
3654
|
+
});
|
|
3655
|
+
});
|
|
3656
|
+
}
|
|
3657
|
+
schedulePump() {
|
|
3658
|
+
if (this.pumpScheduled || this.running || this.pending.length === 0) {
|
|
3659
|
+
return;
|
|
3660
|
+
}
|
|
3661
|
+
this.pumpScheduled = true;
|
|
3662
|
+
this.scheduleTask(() => {
|
|
3663
|
+
this.pumpScheduled = false;
|
|
3664
|
+
void this.runNext();
|
|
3665
|
+
});
|
|
3666
|
+
}
|
|
3667
|
+
takeNextEligibleEntry() {
|
|
3668
|
+
if (this.pending.length === 0) {
|
|
3669
|
+
return void 0;
|
|
3670
|
+
}
|
|
3671
|
+
const now = this.now();
|
|
3672
|
+
let earliestWaitMs;
|
|
3673
|
+
for (let index = 0; index < this.pending.length; index += 1) {
|
|
3674
|
+
const candidate = this.pending[index];
|
|
3675
|
+
if (!candidate) {
|
|
3676
|
+
continue;
|
|
3677
|
+
}
|
|
3678
|
+
const lastRunAt = this.lastRunAtByKey.get(candidate.key);
|
|
3679
|
+
const waitMs = lastRunAt === void 0 ? 0 : lastRunAt + this.minTaskIntervalMs - now;
|
|
3680
|
+
if (waitMs <= 0) {
|
|
3681
|
+
this.pending.splice(index, 1);
|
|
3682
|
+
return { entry: candidate };
|
|
3683
|
+
}
|
|
3684
|
+
earliestWaitMs = earliestWaitMs === void 0 ? waitMs : Math.min(earliestWaitMs, waitMs);
|
|
3685
|
+
}
|
|
3686
|
+
return earliestWaitMs === void 0 ? void 0 : { retryDelayMs: earliestWaitMs };
|
|
3687
|
+
}
|
|
3688
|
+
async runNext() {
|
|
3689
|
+
if (this.running) {
|
|
3690
|
+
return;
|
|
3691
|
+
}
|
|
3692
|
+
const next = this.takeNextEligibleEntry();
|
|
3693
|
+
if (!next) {
|
|
3694
|
+
return;
|
|
3695
|
+
}
|
|
3696
|
+
if (!("entry" in next)) {
|
|
3697
|
+
this.scheduleDelayed(() => {
|
|
3698
|
+
this.schedulePump();
|
|
3699
|
+
}, next.retryDelayMs);
|
|
3700
|
+
return;
|
|
3701
|
+
}
|
|
3702
|
+
this.running = true;
|
|
3703
|
+
const { entry } = next;
|
|
3704
|
+
try {
|
|
3705
|
+
await entry.run();
|
|
3706
|
+
} catch {
|
|
3707
|
+
} finally {
|
|
3708
|
+
this.lastRunAtByKey.set(entry.key, this.now());
|
|
3709
|
+
this.running = false;
|
|
3710
|
+
entry.resolvers.forEach((resolveEntry) => {
|
|
3711
|
+
resolveEntry();
|
|
3712
|
+
});
|
|
3713
|
+
this.schedulePump();
|
|
3714
|
+
}
|
|
3715
|
+
}
|
|
3716
|
+
};
|
|
3717
|
+
|
|
3298
3718
|
// src/editor.tsx
|
|
3299
3719
|
import { Fragment as Fragment2, jsx, jsxs } from "react/jsx-runtime";
|
|
3300
3720
|
var HIGHLIGHT_TO_CSS = {
|
|
@@ -3391,6 +3811,9 @@ var DEFAULT_PARAGRAPH_LINE_MULTIPLE = 1;
|
|
|
3391
3811
|
var WORD_SINGLE_LINE_AUTO_SCALE = 0.88;
|
|
3392
3812
|
var WORD_SINGLE_LINE_AUTO_SCALE_SANS = 0.9;
|
|
3393
3813
|
var WORD_SINGLE_LINE_AUTO_SCALE_SERIF = 1.08;
|
|
3814
|
+
var WORD_EMPTY_PARAGRAPH_LINE_SCALE = 1.21;
|
|
3815
|
+
var WORD_EMPTY_PARAGRAPH_LINE_SCALE_SERIF = 1.15;
|
|
3816
|
+
var WORD_EMPTY_PARAGRAPH_LINE_SCALE_SANS = 1.15;
|
|
3394
3817
|
var WORD_AUTO_LINE_SCALE_BLEND_END_MULTIPLE = 1.08;
|
|
3395
3818
|
var MIN_AUTO_LINE_MULTIPLE = 0.1;
|
|
3396
3819
|
var MIN_PARAGRAPH_LINE_HEIGHT_PX = 14;
|
|
@@ -3435,7 +3858,6 @@ var TEXT_MEASURE_CACHE_MAX_ENTRIES = 12e3;
|
|
|
3435
3858
|
var DEFAULT_TAB_STOP_PX = 48;
|
|
3436
3859
|
var TAB_LEADER_ZONE_GAP_PX = 20;
|
|
3437
3860
|
var EMPTY_PARAGRAPH_EXTRA_HEIGHT_PX = 0;
|
|
3438
|
-
var LEADING_COVER_SPACER_EXTRA_HEIGHT_PX = 2;
|
|
3439
3861
|
var PARAGRAPH_SEGMENT_TOP_BLEED_PX = 22;
|
|
3440
3862
|
var PARAGRAPH_SEGMENT_DESCENDER_BLEED_PX = 6;
|
|
3441
3863
|
var PARAGRAPH_SEGMENT_VISUAL_SAFETY_PX = 24;
|
|
@@ -4302,22 +4724,46 @@ function parseSectionColumns(sectionPropertiesXml) {
|
|
|
4302
4724
|
if (!columnsTag) {
|
|
4303
4725
|
return void 0;
|
|
4304
4726
|
}
|
|
4305
|
-
const numberOfColumnsRaw = columnsTag.match(/w:num="(\d+)"/i)?.[1];
|
|
4306
|
-
const numberOfColumns = numberOfColumnsRaw ? Number(numberOfColumnsRaw) : 1;
|
|
4727
|
+
const numberOfColumnsRaw = columnsTag.match(/w:num="([\d.]+)"/i)?.[1];
|
|
4728
|
+
const numberOfColumns = numberOfColumnsRaw ? Math.round(Number(numberOfColumnsRaw)) : 1;
|
|
4307
4729
|
if (!Number.isFinite(numberOfColumns) || numberOfColumns <= 1) {
|
|
4308
4730
|
return void 0;
|
|
4309
4731
|
}
|
|
4310
|
-
const
|
|
4311
|
-
const
|
|
4732
|
+
const columnCount = Math.max(2, numberOfColumns);
|
|
4733
|
+
const columnTags = [...sectionPropertiesXml.matchAll(/<w:col\b[^>]*\/>/gi)];
|
|
4734
|
+
const widthsTwips = columnTags.map((match) => Number(match[0].match(/w:w="([\d.]+)"/i)?.[1])).filter((value) => Number.isFinite(value) && value > 0);
|
|
4735
|
+
const widthsPx = widthsTwips.map(
|
|
4736
|
+
(value) => Math.max(1, Math.round(twipsToPixels(value) ?? 0))
|
|
4737
|
+
);
|
|
4738
|
+
const colsTagSpaceRaw = columnsTag.match(/w:space="([\d.]+)"/i)?.[1];
|
|
4739
|
+
const firstColSpaceRaw = columnTags.map((match) => match[0].match(/w:space="([\d.]+)"/i)?.[1]).find((value) => value !== void 0);
|
|
4740
|
+
let columnGapTwips = colsTagSpaceRaw !== void 0 ? Number(colsTagSpaceRaw) : firstColSpaceRaw !== void 0 ? Number(firstColSpaceRaw) : void 0;
|
|
4741
|
+
if (columnGapTwips === void 0 && widthsTwips.length === columnCount) {
|
|
4742
|
+
const pageWidthTwips = Number(
|
|
4743
|
+
sectionPropertiesXml.match(/<w:pgSz\b[^>]*w:w="([\d.]+)"/i)?.[1]
|
|
4744
|
+
);
|
|
4745
|
+
const marginTag = sectionPropertiesXml.match(/<w:pgMar\b[^>]*\/?>/i)?.[0];
|
|
4746
|
+
const marginLeftTwips = Number(marginTag?.match(/w:left="([\d.-]+)"/i)?.[1]);
|
|
4747
|
+
const marginRightTwips = Number(
|
|
4748
|
+
marginTag?.match(/w:right="([\d.-]+)"/i)?.[1]
|
|
4749
|
+
);
|
|
4750
|
+
if (Number.isFinite(pageWidthTwips) && Number.isFinite(marginLeftTwips) && Number.isFinite(marginRightTwips)) {
|
|
4751
|
+
const bodyTwips = pageWidthTwips - marginLeftTwips - marginRightTwips;
|
|
4752
|
+
const totalWidthTwips = widthsTwips.reduce((sum, value) => sum + value, 0);
|
|
4753
|
+
columnGapTwips = Math.max(
|
|
4754
|
+
0,
|
|
4755
|
+
(bodyTwips - totalWidthTwips) / Math.max(1, columnCount - 1)
|
|
4756
|
+
);
|
|
4757
|
+
}
|
|
4758
|
+
}
|
|
4759
|
+
if (columnGapTwips === void 0 || !Number.isFinite(columnGapTwips)) {
|
|
4760
|
+
columnGapTwips = 720;
|
|
4761
|
+
}
|
|
4312
4762
|
const columnGapPx = twipsToPixels(columnGapTwips) ?? 24;
|
|
4313
|
-
const columnWidthTags = [
|
|
4314
|
-
...sectionPropertiesXml.matchAll(/<w:col\b[^>]*w:w="(\d+)"[^>]*\/>/gi)
|
|
4315
|
-
];
|
|
4316
|
-
const widthsPx = columnWidthTags.map((match) => Number(match[1])).filter((value) => Number.isFinite(value) && value > 0).map((value) => Math.max(1, Math.round(twipsToPixels(value) ?? 0)));
|
|
4317
4763
|
return {
|
|
4318
|
-
count:
|
|
4764
|
+
count: columnCount,
|
|
4319
4765
|
gapPx: Math.max(0, columnGapPx),
|
|
4320
|
-
...widthsPx.length ===
|
|
4766
|
+
...widthsPx.length === columnCount ? { widthsPx } : void 0
|
|
4321
4767
|
};
|
|
4322
4768
|
}
|
|
4323
4769
|
function resolveSectionPaginationContentWidthPx(layout, sectionPropertiesXml) {
|
|
@@ -5931,19 +6377,6 @@ function floatingTextBoxVisibleTextFromImage(image) {
|
|
|
5931
6377
|
const normalized = normalizeFloatingTextBoxComparisonText(text);
|
|
5932
6378
|
return normalized.length > 0 ? normalized : void 0;
|
|
5933
6379
|
}
|
|
5934
|
-
function absoluteFloatingTextBearingTextBoxFootprintPx(image) {
|
|
5935
|
-
const floating = image.floating;
|
|
5936
|
-
if (!shouldRenderAbsoluteFloatingImage(image) || !floating || image.syntheticTextBox !== true || syntheticTextBoxContainsPictureLayer(image) || !floatingTextBoxVisibleTextFromImage(image)) {
|
|
5937
|
-
return 0;
|
|
5938
|
-
}
|
|
5939
|
-
const imageHeightPx = Number.isFinite(image.heightPx) && image.heightPx > 0 ? Math.round(image.heightPx) : Number.isFinite(image.widthPx) && image.widthPx > 0 ? Math.round(image.widthPx) : MIN_PARAGRAPH_LINE_HEIGHT_PX;
|
|
5940
|
-
const distTPx = Math.max(0, Math.round(floating.distTPx ?? 0));
|
|
5941
|
-
const distBPx = Math.max(0, Math.round(floating.distBPx ?? 0));
|
|
5942
|
-
return Math.max(
|
|
5943
|
-
MIN_PARAGRAPH_LINE_HEIGHT_PX,
|
|
5944
|
-
imageHeightPx + distTPx + distBPx
|
|
5945
|
-
);
|
|
5946
|
-
}
|
|
5947
6380
|
function paragraphVisibleTextIsOnlyAbsoluteFloatingTextBoxContent(paragraph) {
|
|
5948
6381
|
if (!paragraphHasVisibleText2(paragraph) || paragraphHasFormField2(paragraph)) {
|
|
5949
6382
|
return false;
|
|
@@ -5976,29 +6409,9 @@ function paragraphHasOnlyWhitespaceText(paragraph) {
|
|
|
5976
6409
|
return child.text.replace(/[\s\u00a0]+/g, "").length === 0;
|
|
5977
6410
|
});
|
|
5978
6411
|
}
|
|
5979
|
-
function paragraphHasActiveNumbering(paragraph) {
|
|
5980
|
-
const numbering = paragraph.style?.numbering;
|
|
5981
|
-
return Boolean(
|
|
5982
|
-
numbering && Number.isFinite(numbering.numId) && Math.round(numbering.numId) > 0
|
|
5983
|
-
);
|
|
5984
|
-
}
|
|
5985
6412
|
function paragraphContainsSectionBreakProperties(paragraph) {
|
|
5986
6413
|
return /<w:sectPr\b/i.test(paragraph.sourceXml ?? "");
|
|
5987
6414
|
}
|
|
5988
|
-
function paragraphTextBearingAbsoluteFloatingTextBoxFootprintPx(paragraph) {
|
|
5989
|
-
if (paragraphHasVisibleText2(paragraph) || paragraphHasFormField2(paragraph) || paragraphContainsSectionBreakProperties(paragraph)) {
|
|
5990
|
-
return 0;
|
|
5991
|
-
}
|
|
5992
|
-
return paragraph.children.reduce((largest, child) => {
|
|
5993
|
-
if (child.type !== "image") {
|
|
5994
|
-
return largest;
|
|
5995
|
-
}
|
|
5996
|
-
return Math.max(
|
|
5997
|
-
largest,
|
|
5998
|
-
absoluteFloatingTextBearingTextBoxFootprintPx(child)
|
|
5999
|
-
);
|
|
6000
|
-
}, 0);
|
|
6001
|
-
}
|
|
6002
6415
|
function paragraphAbsoluteFloatingAnchorsDependOnParagraphFlow(paragraph) {
|
|
6003
6416
|
return paragraph.children.some((child) => {
|
|
6004
6417
|
if (child.type !== "image" || !shouldRenderAbsoluteFloatingImage(child) || child.syntheticTextBox !== true || !floatingTextBoxVisibleTextFromImage(child) || child.floating?.behindDocument !== true) {
|
|
@@ -6090,21 +6503,6 @@ function paragraphParticipatesInLeadingCoverLayout(model, nodeIndex, pageContent
|
|
|
6090
6503
|
}
|
|
6091
6504
|
return sawLikelyCoverArtAnchor;
|
|
6092
6505
|
}
|
|
6093
|
-
function paragraphLikelyFullPageCoverFootprintPx(model, nodeIndex, paragraph, pageContentWidthPx, pageContentHeightPx) {
|
|
6094
|
-
if (!paragraphParticipatesInLeadingCoverLayout(
|
|
6095
|
-
model,
|
|
6096
|
-
nodeIndex,
|
|
6097
|
-
pageContentWidthPx,
|
|
6098
|
-
pageContentHeightPx
|
|
6099
|
-
) || !paragraphIsLikelyFullPageCoverArtAnchor(
|
|
6100
|
-
paragraph,
|
|
6101
|
-
pageContentWidthPx,
|
|
6102
|
-
pageContentHeightPx
|
|
6103
|
-
)) {
|
|
6104
|
-
return 0;
|
|
6105
|
-
}
|
|
6106
|
-
return Math.max(1, Math.round(pageContentHeightPx));
|
|
6107
|
-
}
|
|
6108
6506
|
function fullPageCoverImageRenderKey(nodeIndex, childIndex) {
|
|
6109
6507
|
return `${nodeIndex}:${childIndex}`;
|
|
6110
6508
|
}
|
|
@@ -6143,71 +6541,6 @@ function fullPageCoverAbsoluteFloatingImageStyle(image, layout, options) {
|
|
|
6143
6541
|
zIndex: floating?.behindDocument === true ? 0 : normalizedZIndex
|
|
6144
6542
|
};
|
|
6145
6543
|
}
|
|
6146
|
-
function paragraphActsAsLeadingCoverLayoutSpacer(model, nodeIndex, paragraph, pageContentWidthPx, pageContentHeightPx) {
|
|
6147
|
-
if (nodeIndex <= 0 || !paragraphHasOnlyWhitespaceText(paragraph) || paragraphHasExplicitPageBreak2(paragraph)) {
|
|
6148
|
-
return false;
|
|
6149
|
-
}
|
|
6150
|
-
if (paragraphHasActiveNumbering(paragraph)) {
|
|
6151
|
-
return false;
|
|
6152
|
-
}
|
|
6153
|
-
return paragraphParticipatesInLeadingCoverLayout(
|
|
6154
|
-
model,
|
|
6155
|
-
nodeIndex,
|
|
6156
|
-
pageContentWidthPx,
|
|
6157
|
-
pageContentHeightPx
|
|
6158
|
-
);
|
|
6159
|
-
}
|
|
6160
|
-
function paragraphActsAsLeadingCoverLayoutPreambleSpacer(model, nodeIndex, paragraph, pageContentWidthPx, pageContentHeightPx) {
|
|
6161
|
-
if (!paragraphHasOnlyWhitespaceText(paragraph) || paragraphHasExplicitPageBreak2(paragraph) || paragraphHasActiveNumbering(paragraph)) {
|
|
6162
|
-
return false;
|
|
6163
|
-
}
|
|
6164
|
-
const nextNode = model.nodes[nodeIndex + 1];
|
|
6165
|
-
if (!nextNode || nextNode.type !== "paragraph") {
|
|
6166
|
-
return false;
|
|
6167
|
-
}
|
|
6168
|
-
if (!paragraphParticipatesInLeadingCoverLayout(
|
|
6169
|
-
model,
|
|
6170
|
-
nodeIndex + 1,
|
|
6171
|
-
pageContentWidthPx,
|
|
6172
|
-
pageContentHeightPx
|
|
6173
|
-
)) {
|
|
6174
|
-
return false;
|
|
6175
|
-
}
|
|
6176
|
-
for (let probeIndex = nodeIndex - 1; probeIndex >= 0; probeIndex -= 1) {
|
|
6177
|
-
const previousNode = model.nodes[probeIndex];
|
|
6178
|
-
if (!previousNode || previousNode.type !== "paragraph") {
|
|
6179
|
-
return false;
|
|
6180
|
-
}
|
|
6181
|
-
if (paragraphHasOnlyWhitespaceText(previousNode)) {
|
|
6182
|
-
continue;
|
|
6183
|
-
}
|
|
6184
|
-
if (paragraphHasAbsoluteFloatingImage(previousNode)) {
|
|
6185
|
-
return false;
|
|
6186
|
-
}
|
|
6187
|
-
return !paragraphIsLikelyFullPageCoverArtAnchor(
|
|
6188
|
-
previousNode,
|
|
6189
|
-
pageContentWidthPx,
|
|
6190
|
-
pageContentHeightPx
|
|
6191
|
-
);
|
|
6192
|
-
}
|
|
6193
|
-
return true;
|
|
6194
|
-
}
|
|
6195
|
-
function paragraphStartsNewPageAfterLeadingCoverLayout(model, nodeIndex, paragraph, pageContentWidthPx, pageContentHeightPx) {
|
|
6196
|
-
if (nodeIndex <= 0 || !paragraphStartsNormalFlowContent(paragraph) || paragraphHasExplicitPageBreak2(paragraph) || paragraphHasPageBreakBefore2(paragraph)) {
|
|
6197
|
-
return false;
|
|
6198
|
-
}
|
|
6199
|
-
const previousNode = model.nodes[nodeIndex - 1];
|
|
6200
|
-
if (!previousNode || previousNode.type !== "paragraph") {
|
|
6201
|
-
return false;
|
|
6202
|
-
}
|
|
6203
|
-
return paragraphActsAsLeadingCoverLayoutSpacer(
|
|
6204
|
-
model,
|
|
6205
|
-
nodeIndex - 1,
|
|
6206
|
-
previousNode,
|
|
6207
|
-
pageContentWidthPx,
|
|
6208
|
-
pageContentHeightPx
|
|
6209
|
-
);
|
|
6210
|
-
}
|
|
6211
6544
|
function paragraphLooksLikeCheckboxChoiceRow(paragraph) {
|
|
6212
6545
|
if (paragraph.children.some((child) => child.type === "image")) {
|
|
6213
6546
|
return false;
|
|
@@ -6725,7 +7058,8 @@ function buildParagraphPretextLayoutSource(paragraph, options) {
|
|
|
6725
7058
|
let combinedText = "";
|
|
6726
7059
|
const paragraphBaseFontPx = paragraphBaseFontSizePx(paragraph);
|
|
6727
7060
|
const tabStopPositionsPx = options?.expandTabsForLayout ? resolveParagraphTabStopsPx(paragraph) : [];
|
|
6728
|
-
const
|
|
7061
|
+
const usesCheckboxRowTabFallback = paragraphLooksLikeCheckboxChoiceRow(paragraph);
|
|
7062
|
+
const fallbackTabWidthPx = usesCheckboxRowTabFallback ? checkboxChoiceRowTabWidthPx(paragraph) : DEFAULT_TAB_STOP_PX;
|
|
6729
7063
|
let approximateLineWidthPx = 0;
|
|
6730
7064
|
let lastTextStyle = firstRunStyle(paragraph);
|
|
6731
7065
|
for (let childIndex = 0; childIndex < paragraph.children.length; childIndex += 1) {
|
|
@@ -6791,7 +7125,8 @@ function buildParagraphPretextLayoutSource(paragraph, options) {
|
|
|
6791
7125
|
const tabWidthPx = resolveTabSpacerWidthPx(
|
|
6792
7126
|
tabStopPositionsPx,
|
|
6793
7127
|
approximateLineWidthPx,
|
|
6794
|
-
fallbackTabWidthPx
|
|
7128
|
+
fallbackTabWidthPx,
|
|
7129
|
+
usesCheckboxRowTabFallback
|
|
6795
7130
|
);
|
|
6796
7131
|
const spacerText = buildParagraphPretextTabSpacerText(
|
|
6797
7132
|
tabWidthPx,
|
|
@@ -7540,10 +7875,14 @@ function updateEstimatedLineWidthPxForText(currentLineWidthPx, text, style) {
|
|
|
7540
7875
|
const trailingSegment = segments[segments.length - 1] ?? "";
|
|
7541
7876
|
return estimateTextAdvanceWidthPx(trailingSegment, style);
|
|
7542
7877
|
}
|
|
7543
|
-
function resolveTabSpacerWidthPx(tabStopPositionsPx, currentLineWidthPx, fallbackWidthPx) {
|
|
7878
|
+
function resolveTabSpacerWidthPx(tabStopPositionsPx, currentLineWidthPx, fallbackWidthPx, fixedFallback = false) {
|
|
7544
7879
|
const safeFallback = Math.max(12, Math.round(fallbackWidthPx));
|
|
7545
7880
|
if (tabStopPositionsPx.length === 0) {
|
|
7546
|
-
|
|
7881
|
+
if (fixedFallback) {
|
|
7882
|
+
return safeFallback;
|
|
7883
|
+
}
|
|
7884
|
+
const nextStop2 = (Math.floor((currentLineWidthPx + 0.5) / safeFallback) + 1) * safeFallback;
|
|
7885
|
+
return Math.max(2, Math.round(nextStop2 - currentLineWidthPx));
|
|
7547
7886
|
}
|
|
7548
7887
|
const nextStop = tabStopPositionsPx.find(
|
|
7549
7888
|
(stop) => stop > currentLineWidthPx + 0.5
|
|
@@ -8296,7 +8635,23 @@ function singleLineAutoScaleForFontFamily(fontFamily) {
|
|
|
8296
8635
|
}
|
|
8297
8636
|
return WORD_SINGLE_LINE_AUTO_SCALE;
|
|
8298
8637
|
}
|
|
8638
|
+
function emptyParagraphLineScaleForFontFamily(fontFamily) {
|
|
8639
|
+
const normalized = normalizeFontFamilyToken(fontFamily) ?? fontFamily?.toLowerCase();
|
|
8640
|
+
if (!normalized) {
|
|
8641
|
+
return WORD_EMPTY_PARAGRAPH_LINE_SCALE;
|
|
8642
|
+
}
|
|
8643
|
+
if (normalized === "times roman" || normalized === "times new roman" || normalized === "cambria" || normalized === "garamond" || normalized === "georgia" || normalized === "book antiqua" || normalized === "palatino linotype") {
|
|
8644
|
+
return WORD_EMPTY_PARAGRAPH_LINE_SCALE_SERIF;
|
|
8645
|
+
}
|
|
8646
|
+
if (normalized === "arial") {
|
|
8647
|
+
return WORD_EMPTY_PARAGRAPH_LINE_SCALE_SANS;
|
|
8648
|
+
}
|
|
8649
|
+
return WORD_EMPTY_PARAGRAPH_LINE_SCALE;
|
|
8650
|
+
}
|
|
8299
8651
|
function resolveParagraphSingleLineAutoScale(paragraph, fontFamily) {
|
|
8652
|
+
if (paragraphHasOnlyWhitespaceText(paragraph)) {
|
|
8653
|
+
return emptyParagraphLineScaleForFontFamily(fontFamily);
|
|
8654
|
+
}
|
|
8300
8655
|
const baseScale = singleLineAutoScaleForFontFamily(fontFamily);
|
|
8301
8656
|
return paragraphHasCheckboxFormField(paragraph) ? Math.max(1.08, baseScale) : baseScale;
|
|
8302
8657
|
}
|
|
@@ -9011,36 +9366,6 @@ function resolveMaxPretextLineRangeEndIndexThatFits(layout, startLineIndex, maxE
|
|
|
9011
9366
|
}
|
|
9012
9367
|
return bestEnd;
|
|
9013
9368
|
}
|
|
9014
|
-
function estimateAbsoluteFloatingImageFootprintPx(paragraph, image) {
|
|
9015
|
-
if (!shouldRenderAbsoluteFloatingImage(image)) {
|
|
9016
|
-
return 0;
|
|
9017
|
-
}
|
|
9018
|
-
const floating = image.floating;
|
|
9019
|
-
if (!floating) {
|
|
9020
|
-
return 0;
|
|
9021
|
-
}
|
|
9022
|
-
const wrapType = (floating.wrapType ?? "none").trim().toLowerCase();
|
|
9023
|
-
if (wrapType !== "none") {
|
|
9024
|
-
return 0;
|
|
9025
|
-
}
|
|
9026
|
-
const behavesAsTextBearingFloatingTextBox = image.syntheticTextBox && !syntheticTextBoxContainsPictureLayer(image) && Boolean(floatingTextBoxVisibleTextFromImage(image));
|
|
9027
|
-
if (behavesAsTextBearingFloatingTextBox) {
|
|
9028
|
-
if (paragraphHasVisibleText2(paragraph) || paragraphHasFormField2(paragraph) || paragraphContainsSectionBreakProperties(paragraph)) {
|
|
9029
|
-
return 0;
|
|
9030
|
-
}
|
|
9031
|
-
const imageHeightPx = Number.isFinite(image.heightPx) && image.heightPx > 0 ? Math.round(image.heightPx) : Number.isFinite(image.widthPx) && image.widthPx > 0 ? Math.round(image.widthPx) : MIN_PARAGRAPH_LINE_HEIGHT_PX;
|
|
9032
|
-
const distTPx = Math.max(0, Math.round(floating.distTPx ?? 0));
|
|
9033
|
-
const distBPx = Math.max(0, Math.round(floating.distBPx ?? 0));
|
|
9034
|
-
return Math.max(
|
|
9035
|
-
MIN_PARAGRAPH_LINE_HEIGHT_PX,
|
|
9036
|
-
imageHeightPx + distTPx + distBPx
|
|
9037
|
-
);
|
|
9038
|
-
}
|
|
9039
|
-
if (floating.behindDocument) {
|
|
9040
|
-
return 0;
|
|
9041
|
-
}
|
|
9042
|
-
return 0;
|
|
9043
|
-
}
|
|
9044
9369
|
function resolveAutoLineSpacingMultiple(lineTwips, fallbackMultiple) {
|
|
9045
9370
|
if (!Number.isFinite(lineTwips)) {
|
|
9046
9371
|
return Math.max(MIN_AUTO_LINE_MULTIPLE, fallbackMultiple);
|
|
@@ -9138,8 +9463,15 @@ function estimateParagraphLineHeightPx(paragraph, docGridLinePitchPx, disableDoc
|
|
|
9138
9463
|
docGridMinimumLineHeightPx ?? 0
|
|
9139
9464
|
);
|
|
9140
9465
|
}
|
|
9141
|
-
const
|
|
9142
|
-
|
|
9466
|
+
const resolvedAutoMultiple = resolveAutoLineSpacingMultiple(
|
|
9467
|
+
lineTwips,
|
|
9468
|
+
defaultLineMultiple
|
|
9469
|
+
);
|
|
9470
|
+
const multiple = paragraphHasOnlyWhitespaceText(paragraph) ? Math.max(
|
|
9471
|
+
MIN_AUTO_LINE_MULTIPLE,
|
|
9472
|
+
Number((resolvedAutoMultiple * singleLineScale).toFixed(3))
|
|
9473
|
+
) : calibrateAutoLineSpacingMultiple(
|
|
9474
|
+
resolvedAutoMultiple,
|
|
9143
9475
|
baseFontFamily,
|
|
9144
9476
|
singleLineScale
|
|
9145
9477
|
);
|
|
@@ -9216,19 +9548,6 @@ function estimateParagraphHeightPx(paragraph, availableWidthPx, numberingDefinit
|
|
|
9216
9548
|
estimateWrappedFloatingImageFootprintPx(paragraph, child)
|
|
9217
9549
|
);
|
|
9218
9550
|
}, 0);
|
|
9219
|
-
const absoluteFloatingImageHeightPx = paragraph.children.reduce(
|
|
9220
|
-
(largest, child) => {
|
|
9221
|
-
if (child.type !== "image") {
|
|
9222
|
-
return largest;
|
|
9223
|
-
}
|
|
9224
|
-
return Math.max(
|
|
9225
|
-
largest,
|
|
9226
|
-
estimateAbsoluteFloatingImageFootprintPx(paragraph, child)
|
|
9227
|
-
);
|
|
9228
|
-
},
|
|
9229
|
-
0
|
|
9230
|
-
);
|
|
9231
|
-
const effectiveAbsoluteFloatingImageHeightPx = collapsibleAbsoluteFloatingAnchorOnlyParagraph || decorativeBehindTextAnchorOnlyParagraph ? 0 : absoluteFloatingImageHeightPx;
|
|
9232
9551
|
const emptyParagraphHeightPx = decorativeBehindTextAnchorOnlyParagraph ? 0 : paragraphIsEffectivelyEmpty(paragraph) ? lineHeightPx + EMPTY_PARAGRAPH_EXTRA_HEIGHT_PX : 0;
|
|
9233
9552
|
const topBorderInsetPx = paragraphBorderInsetPx(
|
|
9234
9553
|
paragraph.style?.borders?.top
|
|
@@ -9248,7 +9567,6 @@ function estimateParagraphHeightPx(paragraph, availableWidthPx, numberingDefinit
|
|
|
9248
9567
|
textFlowHeightPx,
|
|
9249
9568
|
inlineImageHeightPx,
|
|
9250
9569
|
wrappedFloatingImageHeightPx,
|
|
9251
|
-
effectiveAbsoluteFloatingImageHeightPx,
|
|
9252
9570
|
emptyParagraphHeightPx
|
|
9253
9571
|
);
|
|
9254
9572
|
if (excludeWrappedFloatingImageFootprint && paragraph.children.some((c) => c.type === "image")) {
|
|
@@ -10257,7 +10575,7 @@ function splitParagraphSegmentForColumnRender(params) {
|
|
|
10257
10575
|
}
|
|
10258
10576
|
};
|
|
10259
10577
|
}
|
|
10260
|
-
function buildRenderColumnSegmentsForPageSection(model, flowSegments, columnWidthsPx, columnHeightPx, numberingDefinitions, docGridLinePitchPxByNodeIndex, measuredParagraphOuterHeightsPxByNodeIndex, balanceColumns = false) {
|
|
10578
|
+
function buildRenderColumnSegmentsForPageSection(model, flowSegments, columnWidthsPx, columnHeightPx, numberingDefinitions, docGridLinePitchPxByNodeIndex, measuredParagraphOuterHeightsPxByNodeIndex, balanceColumns = false, forceColumnBreakNodeIndexes) {
|
|
10261
10579
|
const columnCount = Math.max(1, columnWidthsPx.length);
|
|
10262
10580
|
const columns = Array.from(
|
|
10263
10581
|
{ length: columnCount },
|
|
@@ -10312,6 +10630,10 @@ function buildRenderColumnSegmentsForPageSection(model, flowSegments, columnWidt
|
|
|
10312
10630
|
consumedHeightPx += Math.max(1, Math.round(heightPx));
|
|
10313
10631
|
};
|
|
10314
10632
|
for (const flowSegment of flowSegments) {
|
|
10633
|
+
const isNodeStartSegment = (flowSegment.paragraphLineRange?.startLineIndex ?? 0) === 0 && (flowSegment.tableRowRange?.startRowIndex ?? 0) === 0 && !flowSegment.tableRowSlice;
|
|
10634
|
+
if (isNodeStartSegment && forceColumnBreakNodeIndexes?.has(flowSegment.nodeIndex) && consumedHeightPx > 0) {
|
|
10635
|
+
moveToNextColumn();
|
|
10636
|
+
}
|
|
10315
10637
|
let pendingSegment = flowSegment;
|
|
10316
10638
|
let splitGuard = 0;
|
|
10317
10639
|
while (pendingSegment && splitGuard < 256) {
|
|
@@ -10505,6 +10827,7 @@ function buildDocumentPageNodeSegments(model, pageContentHeightPx, pageContentWi
|
|
|
10505
10827
|
let previousParagraphAfterPx = 0;
|
|
10506
10828
|
let currentMetricsIndex = 0;
|
|
10507
10829
|
let currentSectionPageFlowOriginPx = 0;
|
|
10830
|
+
let committedKeepNextChainEndNodeIndex = -1;
|
|
10508
10831
|
let currentPageContentHeightPx = resolveMetricsPageContentHeightPx(
|
|
10509
10832
|
0,
|
|
10510
10833
|
metricsBySection[0]
|
|
@@ -10563,31 +10886,10 @@ function buildDocumentPageNodeSegments(model, pageContentHeightPx, pageContentWi
|
|
|
10563
10886
|
previousParagraphAfterPx = 0;
|
|
10564
10887
|
continue;
|
|
10565
10888
|
}
|
|
10566
|
-
if (node.type === "paragraph" && paragraphActsAsLeadingCoverLayoutPreambleSpacer(
|
|
10567
|
-
model,
|
|
10568
|
-
nodeIndex,
|
|
10569
|
-
node,
|
|
10570
|
-
nodeMetrics.pageContentWidthPx,
|
|
10571
|
-
nodeMetrics.pageContentHeightPx
|
|
10572
|
-
)) {
|
|
10573
|
-
previousParagraphAfterPx = 0;
|
|
10574
|
-
continue;
|
|
10575
|
-
}
|
|
10576
10889
|
if (node.type === "paragraph" && paragraphActsAsTrailingRenderedPageBreakSpacer(model, nodeIndex, node)) {
|
|
10577
10890
|
previousParagraphAfterPx = 0;
|
|
10578
10891
|
continue;
|
|
10579
10892
|
}
|
|
10580
|
-
if (node.type === "paragraph" && paragraphActsAsLeadingCoverLayoutOverlay(
|
|
10581
|
-
model,
|
|
10582
|
-
nodeIndex,
|
|
10583
|
-
node,
|
|
10584
|
-
nodeMetrics.pageContentWidthPx,
|
|
10585
|
-
nodeMetrics.pageContentHeightPx
|
|
10586
|
-
)) {
|
|
10587
|
-
currentPageSegments.push({ nodeIndex });
|
|
10588
|
-
previousParagraphAfterPx = 0;
|
|
10589
|
-
continue;
|
|
10590
|
-
}
|
|
10591
10893
|
if (node.type === "paragraph" && paragraphActsAsDecorativeBehindTextBackgroundOverlay(node)) {
|
|
10592
10894
|
currentPageSegments.push({ nodeIndex });
|
|
10593
10895
|
previousParagraphAfterPx = 0;
|
|
@@ -10597,22 +10899,6 @@ function buildDocumentPageNodeSegments(model, pageContentHeightPx, pageContentWi
|
|
|
10597
10899
|
continue;
|
|
10598
10900
|
}
|
|
10599
10901
|
if (node.type === "paragraph") {
|
|
10600
|
-
if (paragraphStartsNewPageAfterLeadingCoverLayout(
|
|
10601
|
-
model,
|
|
10602
|
-
nodeIndex,
|
|
10603
|
-
node,
|
|
10604
|
-
nodeMetrics.pageContentWidthPx,
|
|
10605
|
-
nodeMetrics.pageContentHeightPx
|
|
10606
|
-
) && currentPageSegments.length > 0) {
|
|
10607
|
-
startNextPage();
|
|
10608
|
-
pageConsumedHeightPx = 0;
|
|
10609
|
-
previousParagraphAfterPx = 0;
|
|
10610
|
-
currentSectionPageFlowOriginPx = 0;
|
|
10611
|
-
currentPageContentHeightPx = resolveMetricsPageContentHeightPx(
|
|
10612
|
-
currentPageIndex,
|
|
10613
|
-
nodeMetrics
|
|
10614
|
-
);
|
|
10615
|
-
}
|
|
10616
10902
|
if (paragraphHasPageBreakBefore2(node) && currentPageSegments.length > 0) {
|
|
10617
10903
|
startNextPage();
|
|
10618
10904
|
pageConsumedHeightPx = 0;
|
|
@@ -10682,29 +10968,26 @@ function buildDocumentPageNodeSegments(model, pageContentHeightPx, pageContentWi
|
|
|
10682
10968
|
const nodeNumberingLabel = paginationNumberingLabels.get(
|
|
10683
10969
|
`p:${nodeIndex}`
|
|
10684
10970
|
);
|
|
10685
|
-
|
|
10686
|
-
|
|
10687
|
-
|
|
10688
|
-
node,
|
|
10689
|
-
nodeMetrics.pageContentWidthPx,
|
|
10690
|
-
numberingDefinitions,
|
|
10691
|
-
nodeMetrics.docGridLinePitchPx,
|
|
10692
|
-
false,
|
|
10693
|
-
nodeNumberingLabel
|
|
10694
|
-
) - directBeforeSpacingPx - directAfterSpacingPx + beforeSpacingPx + afterSpacingPx
|
|
10695
|
-
);
|
|
10696
|
-
const coverFootprintPx = paragraphLikelyFullPageCoverFootprintPx(
|
|
10697
|
-
model,
|
|
10698
|
-
nodeIndex,
|
|
10971
|
+
const sectionUsesColumnFlow = (nodeMetrics.pageContentHeightMultiplier ?? 1) > 1;
|
|
10972
|
+
const measuredOuterHeightPx = sectionUsesColumnFlow ? options?.measuredParagraphOuterHeightsPxByNodeIndex?.get(nodeIndex) : void 0;
|
|
10973
|
+
const estimatedOrMeasuredHeightPx = Number.isFinite(measuredOuterHeightPx) && measuredOuterHeightPx > 0 ? measuredOuterHeightPx : estimateParagraphHeightPx(
|
|
10699
10974
|
node,
|
|
10700
10975
|
nodeMetrics.pageContentWidthPx,
|
|
10701
|
-
|
|
10976
|
+
numberingDefinitions,
|
|
10977
|
+
nodeMetrics.docGridLinePitchPx,
|
|
10978
|
+
false,
|
|
10979
|
+
nodeNumberingLabel
|
|
10980
|
+
);
|
|
10981
|
+
let rawNodeHeightPx = Math.max(
|
|
10982
|
+
1,
|
|
10983
|
+
estimatedOrMeasuredHeightPx - directBeforeSpacingPx - directAfterSpacingPx + beforeSpacingPx + afterSpacingPx
|
|
10702
10984
|
);
|
|
10703
|
-
const paragraphTooTallForSinglePage =
|
|
10985
|
+
const paragraphTooTallForSinglePage = rawNodeHeightPx > nodeMetrics.pageContentHeightPx + PAGE_OVERFLOW_TOLERANCE_PX;
|
|
10704
10986
|
const keepLinesOverflowSplit = node.style?.keepLines === true && paragraphTooTallForSinglePage;
|
|
10705
10987
|
const keepNextOverflowSplit = node.style?.keepNext === true && paragraphTooTallForSinglePage;
|
|
10706
10988
|
const forceOverflowSplit = keepLinesOverflowSplit || keepNextOverflowSplit;
|
|
10707
|
-
|
|
10989
|
+
const nodeIsWithinCommittedKeepNextChain = nodeIndex <= committedKeepNextChainEndNodeIndex;
|
|
10990
|
+
if (forceOverflowSplit && !nodeIsWithinCommittedKeepNextChain && pageConsumedHeightPx > 0 && currentPageSegments.length > 0) {
|
|
10708
10991
|
startNextPage();
|
|
10709
10992
|
pageConsumedHeightPx = 0;
|
|
10710
10993
|
previousParagraphAfterPx = 0;
|
|
@@ -10717,7 +11000,7 @@ function buildDocumentPageNodeSegments(model, pageContentHeightPx, pageContentWi
|
|
|
10717
11000
|
const collapsedMarginPx = pageConsumedHeightPx > 0 ? Math.min(previousParagraphAfterPx, beforeSpacingPx) : 0;
|
|
10718
11001
|
const collapsedNodeHeightPx = Math.max(
|
|
10719
11002
|
1,
|
|
10720
|
-
|
|
11003
|
+
rawNodeHeightPx - collapsedMarginPx
|
|
10721
11004
|
);
|
|
10722
11005
|
const paragraphSupportsPretextSegmentRendering = Boolean(
|
|
10723
11006
|
paragraphPretextSourceForSegmentRendering
|
|
@@ -10743,7 +11026,7 @@ function buildDocumentPageNodeSegments(model, pageContentHeightPx, pageContentWi
|
|
|
10743
11026
|
}
|
|
10744
11027
|
const collapsedNodeHeightPxAdjusted = Math.max(
|
|
10745
11028
|
1,
|
|
10746
|
-
|
|
11029
|
+
rawNodeHeightPx - collapsedMarginPx
|
|
10747
11030
|
);
|
|
10748
11031
|
const paragraphPretextLineCount = paragraphContainsExplicitLineBreakText(node) || paragraphContainsTabCharacter(node) ? resolveParagraphPretextLayoutForSegmentRendering()?.lineCount : void 0;
|
|
10749
11032
|
const supportsImageParagraphLineSplit = paragraphHasImage2(node) && paragraphSupportsPretextSegmentRendering;
|
|
@@ -10967,7 +11250,8 @@ function buildDocumentPageNodeSegments(model, pageContentHeightPx, pageContentWi
|
|
|
10967
11250
|
continue;
|
|
10968
11251
|
}
|
|
10969
11252
|
let requiredHeightPx = collapsedNodeHeightPxAdjusted;
|
|
10970
|
-
|
|
11253
|
+
let keepNextChainEndNodeIndex = -1;
|
|
11254
|
+
if (node.style?.keepNext === true && !nodeIsWithinCommittedKeepNextChain && paragraphHasVisibleText2(node)) {
|
|
10971
11255
|
let chainCursor = nodeIndex;
|
|
10972
11256
|
let chainPreviousParagraphAfterPx = afterSpacingPx;
|
|
10973
11257
|
while (chainCursor < model.nodes.length - 1) {
|
|
@@ -11027,6 +11311,7 @@ function buildDocumentPageNodeSegments(model, pageContentHeightPx, pageContentWi
|
|
|
11027
11311
|
);
|
|
11028
11312
|
chainPreviousParagraphAfterPx = nextAfterSpacingPx;
|
|
11029
11313
|
}
|
|
11314
|
+
keepNextChainEndNodeIndex = chainCursor;
|
|
11030
11315
|
}
|
|
11031
11316
|
const remainingHeightPx = currentPageContentHeightPx - pageConsumedHeightPx;
|
|
11032
11317
|
const canKeepTrailingSectionTailOnCurrentPage = shouldKeepTrailingSectionTailOnCurrentPage(
|
|
@@ -11068,11 +11353,11 @@ function buildDocumentPageNodeSegments(model, pageContentHeightPx, pageContentWi
|
|
|
11068
11353
|
nodeMetrics
|
|
11069
11354
|
);
|
|
11070
11355
|
}
|
|
11356
|
+
if (pageConsumedHeightPx === 0 && keepNextChainEndNodeIndex > nodeIndex) {
|
|
11357
|
+
committedKeepNextChainEndNodeIndex = keepNextChainEndNodeIndex;
|
|
11358
|
+
}
|
|
11071
11359
|
currentPageSegments.push({ nodeIndex });
|
|
11072
|
-
const effectiveNodeHeightPx =
|
|
11073
|
-
pageConsumedHeightPx > 0 ? collapsedNodeHeightPx : rawNodeHeightPx,
|
|
11074
|
-
coverFootprintPx
|
|
11075
|
-
);
|
|
11360
|
+
const effectiveNodeHeightPx = pageConsumedHeightPx > 0 ? collapsedNodeHeightPx : rawNodeHeightPx;
|
|
11076
11361
|
pageConsumedHeightPx += effectiveNodeHeightPx;
|
|
11077
11362
|
previousParagraphAfterPx = afterSpacingPx;
|
|
11078
11363
|
continue;
|
|
@@ -11879,11 +12164,15 @@ function paragraphLineHeight(paragraph, docGridLinePitchPx, disableDocGridSnap =
|
|
|
11879
12164
|
disableDocGridSnap
|
|
11880
12165
|
)}px`;
|
|
11881
12166
|
}
|
|
11882
|
-
const
|
|
11883
|
-
|
|
11884
|
-
|
|
11885
|
-
|
|
11886
|
-
|
|
12167
|
+
const resolvedAutoMultiple = resolveAutoLineSpacingMultiple(
|
|
12168
|
+
lineTwips,
|
|
12169
|
+
DEFAULT_PARAGRAPH_LINE_MULTIPLE
|
|
12170
|
+
);
|
|
12171
|
+
const lineMultiple = paragraphHasOnlyWhitespaceText(paragraph) ? Math.max(
|
|
12172
|
+
MIN_AUTO_LINE_MULTIPLE,
|
|
12173
|
+
Number((resolvedAutoMultiple * singleLineScale).toFixed(3))
|
|
12174
|
+
) : calibrateAutoLineSpacingMultiple(
|
|
12175
|
+
resolvedAutoMultiple,
|
|
11887
12176
|
baseFontFamily,
|
|
11888
12177
|
singleLineScale
|
|
11889
12178
|
);
|
|
@@ -12227,8 +12516,7 @@ function paragraphBlockStyle(paragraph, numberingDefinitions, headingStyles, doc
|
|
|
12227
12516
|
const suppressIndentForFloatingAnchorOnlyParagraph = paragraphIsFloatingImageAnchorOnly(paragraph);
|
|
12228
12517
|
const suppressStackingContextForBehindTextAnchorOnlyParagraph = paragraphIsBehindTextAbsoluteFloatingImageAnchorOnly(paragraph);
|
|
12229
12518
|
const suppressFlowFootprintForBehindTextAnchorOnlyParagraph = paragraphActsAsDecorativeBehindTextBackgroundOverlay(paragraph);
|
|
12230
|
-
const
|
|
12231
|
-
const reservedMinHeightPx = suppressFlowFootprintForBehindTextAnchorOnlyParagraph ? void 0 : textBearingAbsoluteFloatingTextBoxFootprintPx > 0 ? textBearingAbsoluteFloatingTextBoxFootprintPx : paragraphIsEffectivelyEmpty(paragraph) ? estimateParagraphLineHeightPx(
|
|
12519
|
+
const reservedMinHeightPx = suppressFlowFootprintForBehindTextAnchorOnlyParagraph ? void 0 : paragraphIsEffectivelyEmpty(paragraph) ? estimateParagraphLineHeightPx(
|
|
12232
12520
|
paragraph,
|
|
12233
12521
|
docGridLinePitchPx,
|
|
12234
12522
|
disableDocGridSnap
|
|
@@ -13986,7 +14274,8 @@ function renderParagraphRuns(paragraph, keyPrefix, documentTheme = "light", numb
|
|
|
13986
14274
|
const resolveNextTabWidthPx = () => resolveTabSpacerWidthPx(
|
|
13987
14275
|
tabStopPositionsPx,
|
|
13988
14276
|
approximateLineWidthPx,
|
|
13989
|
-
fallbackTabWidthPx
|
|
14277
|
+
fallbackTabWidthPx,
|
|
14278
|
+
checkboxChoiceRow
|
|
13990
14279
|
);
|
|
13991
14280
|
const appendPlainTextWithSoftBreakControl = (target, keySeed, text, style, measureStyle) => {
|
|
13992
14281
|
const shouldControlSoftBreakStretch = paragraph.style?.align === "justify" && text.includes("\n");
|
|
@@ -15741,6 +16030,10 @@ function columnWidthsFromTableDefinition(table, columnCount) {
|
|
|
15741
16030
|
const gridWidths = table.style?.columnWidthsTwips;
|
|
15742
16031
|
const rowDerivedWidths = deriveColumnWidthsFromTableRows(table, columnCount);
|
|
15743
16032
|
if (gridWidths && gridWidths.length === columnCount) {
|
|
16033
|
+
console.log("[colw]", columnCount, gridWidths.length, !!rowDerivedWidths, gridConflictsWithRowWidths(table, gridWidths));
|
|
16034
|
+
if (rowDerivedWidths && rowDerivedWidths.length > 0 && gridConflictsWithRowWidths(table, gridWidths)) {
|
|
16035
|
+
return rowDerivedWidths;
|
|
16036
|
+
}
|
|
15744
16037
|
return normalizeColumnWidthsTwips(gridWidths, columnCount);
|
|
15745
16038
|
}
|
|
15746
16039
|
if (rowDerivedWidths && rowDerivedWidths.length > 0) {
|
|
@@ -15751,6 +16044,35 @@ function columnWidthsFromTableDefinition(table, columnCount) {
|
|
|
15751
16044
|
}
|
|
15752
16045
|
return void 0;
|
|
15753
16046
|
}
|
|
16047
|
+
function gridConflictsWithRowWidths(table, gridWidths) {
|
|
16048
|
+
let conflictRows = 0;
|
|
16049
|
+
let measuredRows = 0;
|
|
16050
|
+
for (const row of table.rows) {
|
|
16051
|
+
let columnCursor = 0;
|
|
16052
|
+
let measuredCells = 0;
|
|
16053
|
+
let conflictCells = 0;
|
|
16054
|
+
for (const cell of row.cells) {
|
|
16055
|
+
const span = cell.style?.gridSpan && cell.style.gridSpan > 1 ? cell.style.gridSpan : 1;
|
|
16056
|
+
const expected = gridWidths.slice(columnCursor, columnCursor + span).reduce((sum, value) => sum + Math.max(0, value), 0);
|
|
16057
|
+
columnCursor += span;
|
|
16058
|
+
const actual = cell.style?.widthTwips;
|
|
16059
|
+
if (!actual || actual <= 0 || expected <= 0) {
|
|
16060
|
+
continue;
|
|
16061
|
+
}
|
|
16062
|
+
measuredCells += 1;
|
|
16063
|
+
if (Math.abs(actual - expected) / expected > 0.2) {
|
|
16064
|
+
conflictCells += 1;
|
|
16065
|
+
}
|
|
16066
|
+
}
|
|
16067
|
+
if (measuredCells > 0) {
|
|
16068
|
+
measuredRows += 1;
|
|
16069
|
+
if (conflictCells * 2 > measuredCells) {
|
|
16070
|
+
conflictRows += 1;
|
|
16071
|
+
}
|
|
16072
|
+
}
|
|
16073
|
+
}
|
|
16074
|
+
return measuredRows > 0 && conflictRows * 2 > measuredRows;
|
|
16075
|
+
}
|
|
15754
16076
|
function deriveColumnWidthsFromTableRows(table, columnCount) {
|
|
15755
16077
|
let bestCandidate;
|
|
15756
16078
|
let bestPositiveCount = -1;
|
|
@@ -18970,10 +19292,10 @@ function useDocxEditor(options = {}) {
|
|
|
18970
19292
|
);
|
|
18971
19293
|
const importDocxFile = React.useCallback(
|
|
18972
19294
|
async (file) => {
|
|
18973
|
-
if (!/\.docx
|
|
19295
|
+
if (!/\.docx?$/i.test(file.name)) {
|
|
18974
19296
|
replaceDocumentWithImportError(
|
|
18975
19297
|
file.name,
|
|
18976
|
-
new Error("Only .docx files are supported")
|
|
19298
|
+
new Error("Only .docx and .doc files are supported")
|
|
18977
19299
|
);
|
|
18978
19300
|
return;
|
|
18979
19301
|
}
|
|
@@ -19034,7 +19356,7 @@ function useDocxEditor(options = {}) {
|
|
|
19034
19356
|
const url = URL.createObjectURL(blob);
|
|
19035
19357
|
const anchor = document.createElement("a");
|
|
19036
19358
|
anchor.href = url;
|
|
19037
|
-
anchor.download =
|
|
19359
|
+
anchor.download = /\.docx?$/i.test(fileName) ? fileName.replace(/\.docx?$/i, "") + "-edited.docx" : "edited.docx";
|
|
19038
19360
|
anchor.style.display = "none";
|
|
19039
19361
|
document.body.append(anchor);
|
|
19040
19362
|
anchor.click();
|
|
@@ -22031,12 +22353,32 @@ function ensureDocxViewerPageSurfaceRegistry(editor) {
|
|
|
22031
22353
|
if (!registry) {
|
|
22032
22354
|
registry = {
|
|
22033
22355
|
pageElements: /* @__PURE__ */ new Map(),
|
|
22356
|
+
pageContentKeys: /* @__PURE__ */ new Map(),
|
|
22034
22357
|
listeners: /* @__PURE__ */ new Set()
|
|
22035
22358
|
};
|
|
22036
22359
|
docxViewerPageSurfaceRegistryByEditor.set(owner, registry);
|
|
22037
22360
|
}
|
|
22038
22361
|
return registry;
|
|
22039
22362
|
}
|
|
22363
|
+
function syncDocxViewerPageSurfaceContentKeys(editor, contentKeysByPage) {
|
|
22364
|
+
const registry = ensureDocxViewerPageSurfaceRegistry(editor);
|
|
22365
|
+
let changed = false;
|
|
22366
|
+
contentKeysByPage.forEach((contentKey, pageIndex) => {
|
|
22367
|
+
if (registry.pageContentKeys.get(pageIndex) !== contentKey) {
|
|
22368
|
+
registry.pageContentKeys.set(pageIndex, contentKey);
|
|
22369
|
+
changed = true;
|
|
22370
|
+
}
|
|
22371
|
+
});
|
|
22372
|
+
registry.pageContentKeys.forEach((_, pageIndex) => {
|
|
22373
|
+
if (pageIndex >= contentKeysByPage.length) {
|
|
22374
|
+
registry.pageContentKeys.delete(pageIndex);
|
|
22375
|
+
changed = true;
|
|
22376
|
+
}
|
|
22377
|
+
});
|
|
22378
|
+
if (changed) {
|
|
22379
|
+
notifyDocxViewerPageSurfaceSubscribers(registry);
|
|
22380
|
+
}
|
|
22381
|
+
}
|
|
22040
22382
|
function subscribeDocxViewerPageSurfaces(editor, listener) {
|
|
22041
22383
|
const registry = ensureDocxViewerPageSurfaceRegistry(editor);
|
|
22042
22384
|
registry.listeners.add(listener);
|
|
@@ -22100,62 +22442,8 @@ function resolveDocxViewerPageSurfaceSize(element, fallbackWidthPx, fallbackHeig
|
|
|
22100
22442
|
heightPx: Math.max(1, Math.round(fallbackHeightPx))
|
|
22101
22443
|
};
|
|
22102
22444
|
}
|
|
22103
|
-
|
|
22104
|
-
|
|
22105
|
-
throw new Error("DOCX thumbnails require a browser environment.");
|
|
22106
|
-
}
|
|
22107
|
-
const {
|
|
22108
|
-
pageElement,
|
|
22109
|
-
sourceWidthPx,
|
|
22110
|
-
sourceHeightPx,
|
|
22111
|
-
canvas,
|
|
22112
|
-
widthPx,
|
|
22113
|
-
heightPx,
|
|
22114
|
-
pixelWidthPx,
|
|
22115
|
-
pixelHeightPx
|
|
22116
|
-
} = params;
|
|
22117
|
-
const safeSourceWidthPx = Math.max(1, Math.round(sourceWidthPx));
|
|
22118
|
-
const safeSourceHeightPx = Math.max(1, Math.round(sourceHeightPx));
|
|
22119
|
-
const scaleX = widthPx / safeSourceWidthPx;
|
|
22120
|
-
const scaleY = heightPx / safeSourceHeightPx;
|
|
22121
|
-
const serializedPage = new XMLSerializer().serializeToString(
|
|
22122
|
-
pageElement.cloneNode(true)
|
|
22123
|
-
);
|
|
22124
|
-
const svgMarkup = `
|
|
22125
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="${widthPx}" height="${heightPx}" viewBox="0 0 ${widthPx} ${heightPx}">
|
|
22126
|
-
<foreignObject x="0" y="0" width="100%" height="100%">
|
|
22127
|
-
<div xmlns="http://www.w3.org/1999/xhtml" style="width:${widthPx}px;height:${heightPx}px;overflow:hidden;">
|
|
22128
|
-
<div style="width:${safeSourceWidthPx}px;height:${safeSourceHeightPx}px;transform-origin:top left;transform:scale(${scaleX}, ${scaleY});">
|
|
22129
|
-
${serializedPage}
|
|
22130
|
-
</div>
|
|
22131
|
-
</div>
|
|
22132
|
-
</foreignObject>
|
|
22133
|
-
</svg>
|
|
22134
|
-
`;
|
|
22135
|
-
const svgDataUrl = svgDataUri(svgMarkup);
|
|
22136
|
-
const image = await new Promise((resolve, reject) => {
|
|
22137
|
-
const nextImage = new Image();
|
|
22138
|
-
nextImage.decoding = "async";
|
|
22139
|
-
nextImage.onload = () => resolve(nextImage);
|
|
22140
|
-
nextImage.onerror = () => {
|
|
22141
|
-
reject(new Error("Failed to rasterize DOCX page thumbnail."));
|
|
22142
|
-
};
|
|
22143
|
-
nextImage.src = svgDataUrl;
|
|
22144
|
-
});
|
|
22145
|
-
canvas.width = Math.max(1, Math.round(pixelWidthPx));
|
|
22146
|
-
canvas.height = Math.max(1, Math.round(pixelHeightPx));
|
|
22147
|
-
canvas.style.width = `${Math.max(1, Math.round(widthPx))}px`;
|
|
22148
|
-
canvas.style.height = `${Math.max(1, Math.round(heightPx))}px`;
|
|
22149
|
-
const context = canvas.getContext("2d");
|
|
22150
|
-
if (!context) {
|
|
22151
|
-
throw new Error("2D canvas context is unavailable for DOCX thumbnails.");
|
|
22152
|
-
}
|
|
22153
|
-
context.setTransform(1, 0, 0, 1, 0, 0);
|
|
22154
|
-
context.clearRect(0, 0, canvas.width, canvas.height);
|
|
22155
|
-
context.imageSmoothingEnabled = true;
|
|
22156
|
-
context.imageSmoothingQuality = "high";
|
|
22157
|
-
context.drawImage(image, 0, 0, canvas.width, canvas.height);
|
|
22158
|
-
}
|
|
22445
|
+
var DOCX_THUMBNAIL_SURFACE_CACHE_MAX_ENTRIES = 32;
|
|
22446
|
+
var DOCX_THUMBNAIL_MIN_RASTER_INTERVAL_MS = 200;
|
|
22159
22447
|
function resolveDocxPageThumbnailResolution(options) {
|
|
22160
22448
|
const safeSourceWidthPx = Math.max(1, Math.round(options.sourceWidthPx));
|
|
22161
22449
|
const safeSourceHeightPx = Math.max(1, Math.round(options.sourceHeightPx));
|
|
@@ -22229,8 +22517,51 @@ function useDocxPageThumbnails(editor, options = {}) {
|
|
|
22229
22517
|
},
|
|
22230
22518
|
[]
|
|
22231
22519
|
);
|
|
22520
|
+
const thumbnailSurfaceCacheRef = React.useRef(void 0);
|
|
22521
|
+
const thumbnailRasterQueueRef = React.useRef(void 0);
|
|
22522
|
+
const lastPaintedThumbnailKeyByCanvasRef = React.useRef(
|
|
22523
|
+
/* @__PURE__ */ new WeakMap()
|
|
22524
|
+
);
|
|
22525
|
+
const ensureThumbnailSurfaceCache = React.useCallback(() => {
|
|
22526
|
+
if (!thumbnailSurfaceCacheRef.current) {
|
|
22527
|
+
thumbnailSurfaceCacheRef.current = new DocxThumbnailSurfaceCache(
|
|
22528
|
+
DOCX_THUMBNAIL_SURFACE_CACHE_MAX_ENTRIES
|
|
22529
|
+
);
|
|
22530
|
+
}
|
|
22531
|
+
return thumbnailSurfaceCacheRef.current;
|
|
22532
|
+
}, []);
|
|
22533
|
+
const ensureThumbnailRasterQueue = React.useCallback(() => {
|
|
22534
|
+
if (!thumbnailRasterQueueRef.current) {
|
|
22535
|
+
thumbnailRasterQueueRef.current = new SerialIdleTaskQueue({
|
|
22536
|
+
minTaskIntervalMs: DOCX_THUMBNAIL_MIN_RASTER_INTERVAL_MS
|
|
22537
|
+
});
|
|
22538
|
+
}
|
|
22539
|
+
return thumbnailRasterQueueRef.current;
|
|
22540
|
+
}, []);
|
|
22541
|
+
React.useEffect(() => {
|
|
22542
|
+
thumbnailSurfaceCacheRef.current?.clear();
|
|
22543
|
+
thumbnailRasterQueueRef.current?.clear();
|
|
22544
|
+
lastPaintedThumbnailKeyByCanvasRef.current = /* @__PURE__ */ new WeakMap();
|
|
22545
|
+
}, [editor.documentLoadNonce, pageSurfaceRegistryOwner]);
|
|
22546
|
+
const thumbnailResolutionOptionsKey = React.useMemo(() => {
|
|
22547
|
+
const bounds = options.resolution;
|
|
22548
|
+
const boundsKey = typeof bounds === "number" ? `n${bounds}` : bounds ? `b${bounds.maxWidth ?? ""}x${bounds.maxHeight ?? ""}` : "";
|
|
22549
|
+
return `${boundsKey}|${options.maxWidthPx ?? ""}|${options.maxHeightPx ?? ""}|${options.pixelRatio ?? ""}`;
|
|
22550
|
+
}, [
|
|
22551
|
+
options.maxHeightPx,
|
|
22552
|
+
options.maxWidthPx,
|
|
22553
|
+
options.pixelRatio,
|
|
22554
|
+
options.resolution
|
|
22555
|
+
]);
|
|
22556
|
+
const thumbnailSkipKeyForPage = React.useCallback(
|
|
22557
|
+
(pageIndex) => {
|
|
22558
|
+
const contentKey = pageSurfaceRegistry.pageContentKeys.get(pageIndex);
|
|
22559
|
+
return contentKey === void 0 ? void 0 : `${contentKey}|${editor.documentTheme}|${thumbnailResolutionOptionsKey}`;
|
|
22560
|
+
},
|
|
22561
|
+
[editor.documentTheme, pageSurfaceRegistry, thumbnailResolutionOptionsKey]
|
|
22562
|
+
);
|
|
22232
22563
|
const renderPageThumbnailToCanvas = React.useCallback(
|
|
22233
|
-
async (pageIndex, canvas) => {
|
|
22564
|
+
async (pageIndex, canvas, renderOptions) => {
|
|
22234
22565
|
if (options.disabled) {
|
|
22235
22566
|
return;
|
|
22236
22567
|
}
|
|
@@ -22238,63 +22569,101 @@ function useDocxPageThumbnails(editor, options = {}) {
|
|
|
22238
22569
|
if (!targetCanvas) {
|
|
22239
22570
|
return;
|
|
22240
22571
|
}
|
|
22241
|
-
const pageElement =
|
|
22572
|
+
const pageElement = pageSurfaceRegistry.pageElements.get(pageIndex);
|
|
22242
22573
|
if (!pageElement || !pageElement.isConnected) {
|
|
22243
22574
|
updatePageThumbnailState(pageIndex, "unavailable");
|
|
22244
22575
|
return;
|
|
22245
22576
|
}
|
|
22246
|
-
const
|
|
22247
|
-
|
|
22248
|
-
|
|
22249
|
-
|
|
22250
|
-
|
|
22251
|
-
|
|
22252
|
-
sourceWidthPx: sourceSize.widthPx,
|
|
22253
|
-
sourceHeightPx: sourceSize.heightPx,
|
|
22254
|
-
resolution: options.resolution,
|
|
22255
|
-
maxWidthPx: options.maxWidthPx,
|
|
22256
|
-
maxHeightPx: options.maxHeightPx,
|
|
22257
|
-
pixelRatio: options.pixelRatio
|
|
22258
|
-
});
|
|
22577
|
+
const force = renderOptions?.force === true;
|
|
22578
|
+
const lastPaintedKey = lastPaintedThumbnailKeyByCanvasRef.current.get(targetCanvas);
|
|
22579
|
+
if (!force && lastPaintedKey !== void 0 && lastPaintedKey === thumbnailSkipKeyForPage(pageIndex)) {
|
|
22580
|
+
updatePageThumbnailState(pageIndex, "ready");
|
|
22581
|
+
return;
|
|
22582
|
+
}
|
|
22259
22583
|
updatePageThumbnailState(pageIndex, "rendering");
|
|
22260
|
-
|
|
22261
|
-
|
|
22262
|
-
|
|
22584
|
+
await ensureThumbnailRasterQueue().enqueue(targetCanvas, async () => {
|
|
22585
|
+
const livePageElement = pageSurfaceRegistry.pageElements.get(pageIndex);
|
|
22586
|
+
if (!livePageElement || !livePageElement.isConnected) {
|
|
22587
|
+
updatePageThumbnailState(pageIndex, "unavailable");
|
|
22588
|
+
return;
|
|
22589
|
+
}
|
|
22590
|
+
const runSkipKey = thumbnailSkipKeyForPage(pageIndex);
|
|
22591
|
+
const sourceSize = resolveDocxViewerPageSurfaceSize(
|
|
22592
|
+
livePageElement,
|
|
22593
|
+
fallbackLayout.pageWidthPx,
|
|
22594
|
+
fallbackLayout.pageHeightPx
|
|
22595
|
+
);
|
|
22596
|
+
const resolution = resolveDocxPageThumbnailResolution({
|
|
22263
22597
|
sourceWidthPx: sourceSize.widthPx,
|
|
22264
22598
|
sourceHeightPx: sourceSize.heightPx,
|
|
22265
|
-
|
|
22266
|
-
|
|
22267
|
-
|
|
22268
|
-
|
|
22269
|
-
pixelHeightPx: resolution.pixelHeightPx
|
|
22599
|
+
resolution: options.resolution,
|
|
22600
|
+
maxWidthPx: options.maxWidthPx,
|
|
22601
|
+
maxHeightPx: options.maxHeightPx,
|
|
22602
|
+
pixelRatio: options.pixelRatio
|
|
22270
22603
|
});
|
|
22271
|
-
|
|
22272
|
-
|
|
22273
|
-
|
|
22274
|
-
|
|
22275
|
-
|
|
22276
|
-
|
|
22277
|
-
|
|
22278
|
-
|
|
22604
|
+
const surfaceKey = runSkipKey === void 0 ? void 0 : `${runSkipKey}|${sourceSize.widthPx}x${sourceSize.heightPx}|${resolution.pixelWidthPx}x${resolution.pixelHeightPx}`;
|
|
22605
|
+
const surfaceCache = ensureThumbnailSurfaceCache();
|
|
22606
|
+
try {
|
|
22607
|
+
let surface = !force && surfaceKey !== void 0 ? surfaceCache.get(surfaceKey) : void 0;
|
|
22608
|
+
if (!surface) {
|
|
22609
|
+
surface = await rasterizeDocxThumbnailSurface({
|
|
22610
|
+
pageElement: livePageElement,
|
|
22611
|
+
sourceWidthPx: sourceSize.widthPx,
|
|
22612
|
+
sourceHeightPx: sourceSize.heightPx,
|
|
22613
|
+
widthPx: resolution.widthPx,
|
|
22614
|
+
heightPx: resolution.heightPx,
|
|
22615
|
+
pixelWidthPx: resolution.pixelWidthPx,
|
|
22616
|
+
pixelHeightPx: resolution.pixelHeightPx
|
|
22617
|
+
});
|
|
22618
|
+
if (surfaceKey !== void 0) {
|
|
22619
|
+
surfaceCache.set(surfaceKey, surface);
|
|
22620
|
+
}
|
|
22621
|
+
}
|
|
22622
|
+
blitDocxThumbnailSurface(surface, targetCanvas, resolution);
|
|
22623
|
+
if (runSkipKey !== void 0) {
|
|
22624
|
+
lastPaintedThumbnailKeyByCanvasRef.current.set(
|
|
22625
|
+
targetCanvas,
|
|
22626
|
+
runSkipKey
|
|
22627
|
+
);
|
|
22628
|
+
}
|
|
22629
|
+
updatePageThumbnailState(pageIndex, "ready");
|
|
22630
|
+
} catch (error) {
|
|
22631
|
+
updatePageThumbnailState(
|
|
22632
|
+
pageIndex,
|
|
22633
|
+
"error",
|
|
22634
|
+
error instanceof Error ? error : new Error("Failed to render DOCX page thumbnail.")
|
|
22635
|
+
);
|
|
22636
|
+
}
|
|
22637
|
+
});
|
|
22279
22638
|
},
|
|
22280
22639
|
[
|
|
22640
|
+
ensureThumbnailRasterQueue,
|
|
22641
|
+
ensureThumbnailSurfaceCache,
|
|
22281
22642
|
fallbackLayout.pageHeightPx,
|
|
22282
22643
|
fallbackLayout.pageWidthPx,
|
|
22283
|
-
mountedPageElements,
|
|
22284
22644
|
options.disabled,
|
|
22285
22645
|
options.resolution,
|
|
22286
22646
|
options.maxHeightPx,
|
|
22287
22647
|
options.maxWidthPx,
|
|
22288
22648
|
options.pixelRatio,
|
|
22649
|
+
pageSurfaceRegistry,
|
|
22650
|
+
thumbnailSkipKeyForPage,
|
|
22289
22651
|
updatePageThumbnailState
|
|
22290
22652
|
]
|
|
22291
22653
|
);
|
|
22292
|
-
const
|
|
22293
|
-
|
|
22294
|
-
|
|
22295
|
-
|
|
22296
|
-
|
|
22297
|
-
|
|
22654
|
+
const requestAttachedThumbnailRenders = React.useCallback(
|
|
22655
|
+
async (renderOptions) => {
|
|
22656
|
+
const tasks = [...attachedCanvasByPageRef.current.keys()].map(
|
|
22657
|
+
(pageIndex) => renderPageThumbnailToCanvas(pageIndex, void 0, renderOptions)
|
|
22658
|
+
);
|
|
22659
|
+
await Promise.all(tasks);
|
|
22660
|
+
},
|
|
22661
|
+
[renderPageThumbnailToCanvas]
|
|
22662
|
+
);
|
|
22663
|
+
const rerenderAttachedThumbnails = React.useCallback(
|
|
22664
|
+
async () => requestAttachedThumbnailRenders({ force: true }),
|
|
22665
|
+
[requestAttachedThumbnailRenders]
|
|
22666
|
+
);
|
|
22298
22667
|
const renderPageThumbnailToCanvasRef = React.useRef(
|
|
22299
22668
|
renderPageThumbnailToCanvas
|
|
22300
22669
|
);
|
|
@@ -22306,7 +22675,7 @@ function useDocxPageThumbnails(editor, options = {}) {
|
|
|
22306
22675
|
renderToCanvasCallbacksRef.current.clear();
|
|
22307
22676
|
}, [pageSurfaceRegistryOwner]);
|
|
22308
22677
|
React.useEffect(() => {
|
|
22309
|
-
void
|
|
22678
|
+
void requestAttachedThumbnailRenders();
|
|
22310
22679
|
}, [
|
|
22311
22680
|
editor.documentLoadNonce,
|
|
22312
22681
|
editor.documentTheme,
|
|
@@ -22317,7 +22686,7 @@ function useDocxPageThumbnails(editor, options = {}) {
|
|
|
22317
22686
|
options.maxHeightPx,
|
|
22318
22687
|
options.maxWidthPx,
|
|
22319
22688
|
options.pixelRatio,
|
|
22320
|
-
|
|
22689
|
+
requestAttachedThumbnailRenders
|
|
22321
22690
|
]);
|
|
22322
22691
|
const thumbnails = React.useMemo(() => {
|
|
22323
22692
|
const totalPages = Math.max(1, editor.totalPages);
|
|
@@ -24188,7 +24557,8 @@ function DocxEditorViewer({
|
|
|
24188
24557
|
preferLastRenderedParagraphStartBreaks,
|
|
24189
24558
|
strictLastRenderedParagraphStartBreaks: paginationOptions?.strictLastRenderedParagraphStartBreaks ?? false,
|
|
24190
24559
|
measuredTableRowHeightsByNodeIndex,
|
|
24191
|
-
measuredPageContentHeightsPxByPageIndex: resolvedPageContentHeights
|
|
24560
|
+
measuredPageContentHeightsPxByPageIndex: resolvedPageContentHeights,
|
|
24561
|
+
measuredParagraphOuterHeightsPxByNodeIndex
|
|
24192
24562
|
}
|
|
24193
24563
|
);
|
|
24194
24564
|
const basePages = buildPagesWithHeights(baseMeasuredHeights);
|
|
@@ -24228,7 +24598,10 @@ function DocxEditorViewer({
|
|
|
24228
24598
|
}
|
|
24229
24599
|
);
|
|
24230
24600
|
const minimumPageCount = Math.max(1, hardBreakCount + 1);
|
|
24231
|
-
const
|
|
24601
|
+
const hasColumnFlowSections = paginationSectionMetrics.some(
|
|
24602
|
+
(metrics) => (metrics.pageContentHeightMultiplier ?? 1) > 1
|
|
24603
|
+
);
|
|
24604
|
+
const targetPageCount = !hasColumnFlowSections && Number.isFinite(storedDocumentPageCount2) && storedDocumentPageCount2 > 0 ? Math.max(
|
|
24232
24605
|
minimumPageCount,
|
|
24233
24606
|
Math.round(storedDocumentPageCount2)
|
|
24234
24607
|
) : void 0;
|
|
@@ -24461,7 +24834,8 @@ function DocxEditorViewer({
|
|
|
24461
24834
|
measuredPageContentHeightsPxByPageIndex: measuredPageContentHeightsOverride === null ? void 0 : scaleMeasuredPageContentHeights(
|
|
24462
24835
|
measuredPageContentHeightsOverride ?? measuredPageContentHeightByIndex,
|
|
24463
24836
|
heightScale
|
|
24464
|
-
)
|
|
24837
|
+
),
|
|
24838
|
+
measuredParagraphOuterHeightsPxByNodeIndex
|
|
24465
24839
|
}
|
|
24466
24840
|
)
|
|
24467
24841
|
});
|
|
@@ -24534,6 +24908,7 @@ function DocxEditorViewer({
|
|
|
24534
24908
|
hasMeasuredBodyFooterOverlap,
|
|
24535
24909
|
initialPaginationBackgroundRefinementUnlocked,
|
|
24536
24910
|
measuredPageContentHeightByIndex,
|
|
24911
|
+
measuredParagraphOuterHeightsPxByNodeIndex,
|
|
24537
24912
|
tableMeasuredRowHeightsForPagination
|
|
24538
24913
|
]);
|
|
24539
24914
|
const pageNodeSegmentsByPage = pageSegmentationPlan.pages;
|
|
@@ -24701,6 +25076,42 @@ function DocxEditorViewer({
|
|
|
24701
25076
|
pageNodeSegmentsByPage,
|
|
24702
25077
|
primarySectionPropertiesXml
|
|
24703
25078
|
]);
|
|
25079
|
+
const pageThumbnailContentKeysByPage = React.useMemo(() => {
|
|
25080
|
+
const metadataSignature = docModelThumbnailMetadataSignature(
|
|
25081
|
+
editor.model.metadata
|
|
25082
|
+
);
|
|
25083
|
+
return pageNodeSegmentsByPage.map((pageSegments, pageIndex) => {
|
|
25084
|
+
const sectionInfo = pageSectionInfoByIndex[pageIndex];
|
|
25085
|
+
let nodeSignatures = "";
|
|
25086
|
+
for (const segment of pageSegments) {
|
|
25087
|
+
nodeSignatures += docNodeContentSignature(
|
|
25088
|
+
editor.model.nodes[segment.nodeIndex]
|
|
25089
|
+
);
|
|
25090
|
+
nodeSignatures += ",";
|
|
25091
|
+
}
|
|
25092
|
+
return [
|
|
25093
|
+
editor.documentLoadNonce,
|
|
25094
|
+
trackedChangesEnabled ? "tc1" : "tc0",
|
|
25095
|
+
metadataSignature,
|
|
25096
|
+
sectionInfo ? `${sectionInfo.sectionIndex}.${sectionInfo.pageNumber}` : "s?",
|
|
25097
|
+
pageNodeSegmentIdentityKeysByPage[pageIndex] ?? "",
|
|
25098
|
+
nodeSignatures
|
|
25099
|
+
].join("|");
|
|
25100
|
+
});
|
|
25101
|
+
}, [
|
|
25102
|
+
editor.documentLoadNonce,
|
|
25103
|
+
editor.model,
|
|
25104
|
+
pageNodeSegmentIdentityKeysByPage,
|
|
25105
|
+
pageNodeSegmentsByPage,
|
|
25106
|
+
pageSectionInfoByIndex,
|
|
25107
|
+
trackedChangesEnabled
|
|
25108
|
+
]);
|
|
25109
|
+
React.useEffect(() => {
|
|
25110
|
+
syncDocxViewerPageSurfaceContentKeys(
|
|
25111
|
+
editor,
|
|
25112
|
+
pageThumbnailContentKeysByPage
|
|
25113
|
+
);
|
|
25114
|
+
}, [pageSurfaceRegistryOwner, pageThumbnailContentKeysByPage]);
|
|
24704
25115
|
const resolveStyleRefFieldValueForPage = React.useMemo(() => {
|
|
24705
25116
|
const valueCache = /* @__PURE__ */ new Map();
|
|
24706
25117
|
const nodes = editor.model.nodes;
|
|
@@ -25260,6 +25671,8 @@ function DocxEditorViewer({
|
|
|
25260
25671
|
setMeasuredParagraphOuterHeightsPxByNodeIndex((current) => {
|
|
25261
25672
|
const next = new Map(current);
|
|
25262
25673
|
let changed = false;
|
|
25674
|
+
const rootElement = viewerRootRef.current;
|
|
25675
|
+
const zoomScale = rootElement ? resolveEffectiveZoomScale(rootElement) : 1;
|
|
25263
25676
|
paragraphElementsRef.current.forEach((element, nodeIndex) => {
|
|
25264
25677
|
if (!element.isConnected || element.dataset.docxParagraphPartialLineRange === "true" || element.closest('[data-docx-header-footer-region="footer"]') || element.closest('[data-docx-header-footer-region="header"]')) {
|
|
25265
25678
|
return;
|
|
@@ -25274,10 +25687,11 @@ function DocxEditorViewer({
|
|
|
25274
25687
|
const outerHeightPx = Math.max(
|
|
25275
25688
|
1,
|
|
25276
25689
|
Math.round(
|
|
25277
|
-
rect.height + (Number.isFinite(marginTop) ? marginTop : 0) + (Number.isFinite(marginBottom) ? marginBottom : 0)
|
|
25690
|
+
rect.height / zoomScale + (Number.isFinite(marginTop) ? marginTop : 0) + (Number.isFinite(marginBottom) ? marginBottom : 0)
|
|
25278
25691
|
)
|
|
25279
25692
|
);
|
|
25280
|
-
|
|
25693
|
+
const previousHeightPx = next.get(nodeIndex);
|
|
25694
|
+
if (previousHeightPx === void 0 || Math.abs(previousHeightPx - outerHeightPx) > 1) {
|
|
25281
25695
|
next.set(nodeIndex, outerHeightPx);
|
|
25282
25696
|
changed = true;
|
|
25283
25697
|
}
|
|
@@ -32414,6 +32828,7 @@ function DocxEditorViewer({
|
|
|
32414
32828
|
"span",
|
|
32415
32829
|
{
|
|
32416
32830
|
contentEditable: false,
|
|
32831
|
+
...{ [DOCX_THUMBNAIL_EXCLUDE_ATTRIBUTE]: "true" },
|
|
32417
32832
|
style: {
|
|
32418
32833
|
position: "absolute",
|
|
32419
32834
|
left: rect.left,
|
|
@@ -32436,6 +32851,7 @@ function DocxEditorViewer({
|
|
|
32436
32851
|
"span",
|
|
32437
32852
|
{
|
|
32438
32853
|
contentEditable: false,
|
|
32854
|
+
...{ [DOCX_THUMBNAIL_EXCLUDE_ATTRIBUTE]: "true" },
|
|
32439
32855
|
style: {
|
|
32440
32856
|
position: "absolute",
|
|
32441
32857
|
left: caretRect.left,
|
|
@@ -34830,7 +35246,7 @@ function DocxEditorViewer({
|
|
|
34830
35246
|
const extractDroppedDocxFile = React.useCallback(
|
|
34831
35247
|
(dataTransfer) => {
|
|
34832
35248
|
return Array.from(dataTransfer?.files ?? []).find(
|
|
34833
|
-
(candidate) => /\.docx
|
|
35249
|
+
(candidate) => /\.docx?$/i.test(candidate.name)
|
|
34834
35250
|
);
|
|
34835
35251
|
},
|
|
34836
35252
|
[]
|
|
@@ -35639,13 +36055,6 @@ function DocxEditorViewer({
|
|
|
35639
36055
|
options?.pageFlowForeignExclusions ?? []
|
|
35640
36056
|
)
|
|
35641
36057
|
);
|
|
35642
|
-
const leadingCoverLayoutSpacer = paragraphActsAsLeadingCoverLayoutSpacer(
|
|
35643
|
-
editor.model,
|
|
35644
|
-
nodeIndex,
|
|
35645
|
-
node,
|
|
35646
|
-
paragraphContentWidthPx,
|
|
35647
|
-
resolvedPageLayout.pageHeightPx - resolvedPageLayout.marginsPx.top - resolvedPageLayout.marginsPx.bottom
|
|
35648
|
-
);
|
|
35649
36058
|
const beforeSpacingPx = effectiveParagraphBeforeSpacingPx(
|
|
35650
36059
|
editor.model,
|
|
35651
36060
|
nodeIndex,
|
|
@@ -35704,9 +36113,6 @@ function DocxEditorViewer({
|
|
|
35704
36113
|
lineHeight: 0,
|
|
35705
36114
|
overflow: "visible"
|
|
35706
36115
|
} : requiresPageAbsoluteContext ? { position: "static" } : requiresLocalAbsoluteContext ? { position: "relative" } : hasDualWrappedFloatingImage ? { position: "relative" } : void 0,
|
|
35707
|
-
...leadingCoverLayoutSpacer ? {
|
|
35708
|
-
minHeight: `${estimateParagraphLineHeightPx(node, nodeDocGridLinePitchPx) + EMPTY_PARAGRAPH_EXTRA_HEIGHT_PX + LEADING_COVER_SPACER_EXTRA_HEIGHT_PX}px`
|
|
35709
|
-
} : void 0,
|
|
35710
36116
|
// Carry the paragraph's run font on the editable host so text typed into
|
|
35711
36117
|
// it (which is a bare, not-yet-committed text node, not a styled run
|
|
35712
36118
|
// span) renders in the same font the committed run will use — i.e. the
|
|
@@ -36741,6 +37147,22 @@ ${currentText.slice(end)}`;
|
|
|
36741
37147
|
const rowSpanValue = cell.style?.rowSpan && cell.style.rowSpan > 1 ? cell.style.rowSpan : 1;
|
|
36742
37148
|
const colSpan = colSpanValue > 1 ? colSpanValue : void 0;
|
|
36743
37149
|
const rowSpan = rowSpanValue > 1 ? rowSpanValue : void 0;
|
|
37150
|
+
const exactRowSpanRows = node.rows.slice(
|
|
37151
|
+
rowIndex,
|
|
37152
|
+
rowIndex + rowSpanValue
|
|
37153
|
+
);
|
|
37154
|
+
const exactRowSpanClipHeightPx = exactRowSpanRows.length > 0 && exactRowSpanRows.every((spannedRow, rowOffset) => {
|
|
37155
|
+
const spannedHeightPx = rowHeightsPx[rowIndex + rowOffset];
|
|
37156
|
+
return spannedRow.style?.heightRule === "exact" && Number.isFinite(spannedHeightPx) && spannedHeightPx > 0;
|
|
37157
|
+
}) ? exactRowSpanRows.reduce(
|
|
37158
|
+
(sum, _spannedRow, rowOffset) => sum + Math.max(
|
|
37159
|
+
MIN_PARAGRAPH_LINE_HEIGHT_PX,
|
|
37160
|
+
Math.round(
|
|
37161
|
+
rowHeightsPx[rowIndex + rowOffset]
|
|
37162
|
+
)
|
|
37163
|
+
),
|
|
37164
|
+
0
|
|
37165
|
+
) : void 0;
|
|
36744
37166
|
const startColumnIndex = columnCursor;
|
|
36745
37167
|
const boundaryColumnIndex = startColumnIndex + colSpanValue - 1;
|
|
36746
37168
|
columnCursor += colSpanValue;
|
|
@@ -37853,7 +38275,23 @@ ${currentText.slice(end)}`;
|
|
|
37853
38275
|
}
|
|
37854
38276
|
)
|
|
37855
38277
|
}
|
|
37856
|
-
) : /* @__PURE__ */ jsx(
|
|
38278
|
+
) : /* @__PURE__ */ jsx(
|
|
38279
|
+
"div",
|
|
38280
|
+
{
|
|
38281
|
+
style: {
|
|
38282
|
+
display: "grid",
|
|
38283
|
+
gap: 0,
|
|
38284
|
+
// Without the clip the row balloons to fit
|
|
38285
|
+
// content (height on a <tr>/<td> is only
|
|
38286
|
+
// ever a minimum).
|
|
38287
|
+
...exactRowSpanClipHeightPx !== void 0 && !isSlicedRow ? {
|
|
38288
|
+
maxHeight: `${exactRowSpanClipHeightPx}px`,
|
|
38289
|
+
overflow: "hidden"
|
|
38290
|
+
} : void 0
|
|
38291
|
+
},
|
|
38292
|
+
children: renderStaticCellContent()
|
|
38293
|
+
}
|
|
38294
|
+
)
|
|
37857
38295
|
},
|
|
37858
38296
|
`cell-${nodeIndex}-${rowIndex}-${cellIndex}`
|
|
37859
38297
|
);
|
|
@@ -39634,13 +40072,30 @@ ${currentText.slice(end)}`;
|
|
|
39634
40072
|
currentGroup.segments.push(segment);
|
|
39635
40073
|
return;
|
|
39636
40074
|
}
|
|
40075
|
+
if (currentGroup && parseSectionStartType(
|
|
40076
|
+
documentSections[currentSectionIndex]?.sectionPropertiesXml
|
|
40077
|
+
) === "nextcolumn") {
|
|
40078
|
+
const previousColumns = sectionColumnsBySectionIndex[currentGroup.sectionIndex];
|
|
40079
|
+
const nextColumns = sectionColumnsBySectionIndex[currentSectionIndex];
|
|
40080
|
+
const sameGeometry = previousColumns && nextColumns && previousColumns.count === nextColumns.count && Math.abs(
|
|
40081
|
+
previousColumns.gapPx - nextColumns.gapPx
|
|
40082
|
+
) <= 2 && JSON.stringify(previousColumns.widthsPx ?? null) === JSON.stringify(nextColumns.widthsPx ?? null);
|
|
40083
|
+
if (sameGeometry) {
|
|
40084
|
+
currentGroup.segments.push(segment);
|
|
40085
|
+
return;
|
|
40086
|
+
}
|
|
40087
|
+
}
|
|
39637
40088
|
sectionGroups.push({
|
|
39638
40089
|
sectionIndex: currentSectionIndex,
|
|
39639
40090
|
segments: [segment]
|
|
39640
40091
|
});
|
|
39641
40092
|
});
|
|
40093
|
+
if (typeof window !== "undefined" && window.__docxDebugGroups) {
|
|
40094
|
+
console.log("[groups]", pageIndex, JSON.stringify(sectionGroups.map((g) => ({ s: g.sectionIndex, n: g.segments.map((x) => x.nodeIndex) }))));
|
|
40095
|
+
}
|
|
39642
40096
|
return sectionGroups.map((group, groupIndex) => {
|
|
39643
40097
|
const sectionColumns = sectionColumnsBySectionIndex[group.sectionIndex];
|
|
40098
|
+
const isLastGroupOnPage = groupIndex === sectionGroups.length - 1;
|
|
39644
40099
|
const overlaySegments = group.segments.filter(
|
|
39645
40100
|
(segment) => {
|
|
39646
40101
|
const segmentNode = editor.model.nodes[segment.nodeIndex];
|
|
@@ -39801,7 +40256,19 @@ ${currentText.slice(end)}`;
|
|
|
39801
40256
|
editor.model.metadata.numberingDefinitions,
|
|
39802
40257
|
docGridLinePitchPxByNodeIndex,
|
|
39803
40258
|
measuredParagraphOuterHeightsPxByNodeIndex,
|
|
39804
|
-
isLastPage
|
|
40259
|
+
isLastPage || !isLastGroupOnPage,
|
|
40260
|
+
new Set(
|
|
40261
|
+
(editor.model.metadata.sections ?? []).filter(
|
|
40262
|
+
(candidate) => parseSectionStartType(
|
|
40263
|
+
candidate.sectionPropertiesXml
|
|
40264
|
+
) === "nextcolumn"
|
|
40265
|
+
).map(
|
|
40266
|
+
(candidate) => Math.max(
|
|
40267
|
+
0,
|
|
40268
|
+
Math.round(candidate.startNodeIndex)
|
|
40269
|
+
)
|
|
40270
|
+
)
|
|
40271
|
+
)
|
|
39805
40272
|
);
|
|
39806
40273
|
return /* @__PURE__ */ jsxs(Fragment2, { children: [
|
|
39807
40274
|
overlaySegments.map((overlaySegment) => {
|
|
@@ -39837,7 +40304,9 @@ ${currentText.slice(end)}`;
|
|
|
39837
40304
|
gridTemplateColumns: columnWidthsPx.map((widthPx) => `${widthPx}px`).join(" "),
|
|
39838
40305
|
columnGap: sectionColumns.gapPx,
|
|
39839
40306
|
alignItems: "start",
|
|
39840
|
-
|
|
40307
|
+
...isLastGroupOnPage ? {
|
|
40308
|
+
minHeight: pageBodyAvailableHeightPx
|
|
40309
|
+
} : void 0,
|
|
39841
40310
|
position: "relative",
|
|
39842
40311
|
zIndex: 1
|
|
39843
40312
|
},
|
|
@@ -39845,9 +40314,9 @@ ${currentText.slice(end)}`;
|
|
|
39845
40314
|
(segmentsForColumn, columnIndex) => /* @__PURE__ */ jsx(
|
|
39846
40315
|
"div",
|
|
39847
40316
|
{
|
|
39848
|
-
style: {
|
|
40317
|
+
style: isLastGroupOnPage ? {
|
|
39849
40318
|
minHeight: pageBodyAvailableHeightPx
|
|
39850
|
-
},
|
|
40319
|
+
} : void 0,
|
|
39851
40320
|
children: segmentsForColumn.map(
|
|
39852
40321
|
(segment) => renderSegmentInColumn(
|
|
39853
40322
|
segment,
|
|
@@ -41702,6 +42171,7 @@ function collectDocxEstimatedOverflowBreakStartNodeIndexes(model, hardBreakStart
|
|
|
41702
42171
|
let pageConsumedHeightPx = 0;
|
|
41703
42172
|
let previousParagraphAfterPx = 0;
|
|
41704
42173
|
let currentMetricsIndex = 0;
|
|
42174
|
+
let committedKeepNextChainEndNodeIndex = -1;
|
|
41705
42175
|
const suppressSpacingBeforeAfterPageBreak = options?.suppressSpacingBeforeAfterPageBreak ?? false;
|
|
41706
42176
|
let currentPageContentHeightPx = metricsBySection[0]?.pageContentHeightPx ?? fallbackMetrics.pageContentHeightPx;
|
|
41707
42177
|
for (let nodeIndex = 0; nodeIndex < model.nodes.length; nodeIndex += 1) {
|
|
@@ -41739,7 +42209,8 @@ function collectDocxEstimatedOverflowBreakStartNodeIndexes(model, hardBreakStart
|
|
|
41739
42209
|
const collapsedMarginPx = node.type === "paragraph" && pageConsumedHeightPx > 0 ? Math.min(previousParagraphAfterPx, nodeBeforeSpacingPx) : 0;
|
|
41740
42210
|
const collapsedNodeHeightPx = Math.max(1, rawNodeHeightPx - collapsedMarginPx);
|
|
41741
42211
|
let requiredHeightPx = collapsedNodeHeightPx;
|
|
41742
|
-
|
|
42212
|
+
let keepNextChainEndNodeIndex = -1;
|
|
42213
|
+
if (node.type === "paragraph" && node.style?.keepNext === true && nodeIndex > committedKeepNextChainEndNodeIndex && callbacks.paragraphHasVisibleText(node)) {
|
|
41743
42214
|
let chainCursor = nodeIndex;
|
|
41744
42215
|
let chainPreviousParagraphAfterPx = paragraphAfterSpacingPx2(node);
|
|
41745
42216
|
while (chainCursor < model.nodes.length - 1) {
|
|
@@ -41797,6 +42268,7 @@ function collectDocxEstimatedOverflowBreakStartNodeIndexes(model, hardBreakStart
|
|
|
41797
42268
|
);
|
|
41798
42269
|
chainPreviousParagraphAfterPx = paragraphAfterSpacingPx2(nextChainNode);
|
|
41799
42270
|
}
|
|
42271
|
+
keepNextChainEndNodeIndex = chainCursor;
|
|
41800
42272
|
}
|
|
41801
42273
|
const remainingHeightPx = currentPageContentHeightPx - pageConsumedHeightPx;
|
|
41802
42274
|
if (pageConsumedHeightPx > 0 && requiredHeightPx > remainingHeightPx + pageOverflowTolerancePx) {
|
|
@@ -41805,6 +42277,9 @@ function collectDocxEstimatedOverflowBreakStartNodeIndexes(model, hardBreakStart
|
|
|
41805
42277
|
previousParagraphAfterPx = 0;
|
|
41806
42278
|
currentPageContentHeightPx = nodeMetrics.pageContentHeightPx;
|
|
41807
42279
|
}
|
|
42280
|
+
if (pageConsumedHeightPx === 0 && keepNextChainEndNodeIndex > nodeIndex) {
|
|
42281
|
+
committedKeepNextChainEndNodeIndex = keepNextChainEndNodeIndex;
|
|
42282
|
+
}
|
|
41808
42283
|
const effectiveNodeHeightPx = pageConsumedHeightPx > 0 ? collapsedNodeHeightPx : rawNodeHeightPx;
|
|
41809
42284
|
pageConsumedHeightPx += effectiveNodeHeightPx;
|
|
41810
42285
|
previousParagraphAfterPx = node.type === "paragraph" ? paragraphAfterSpacingPx2(node) : 0;
|
|
@@ -41856,6 +42331,7 @@ function buildDocumentPageNodeSegments2(model, pageContentHeightPx, pageContentW
|
|
|
41856
42331
|
let pageConsumedHeightPx = 0;
|
|
41857
42332
|
let previousParagraphAfterPx = 0;
|
|
41858
42333
|
let currentMetricsIndex = 0;
|
|
42334
|
+
let committedKeepNextChainEndNodeIndex = -1;
|
|
41859
42335
|
let currentPageContentHeightPx = resolvePageContentHeightPx(
|
|
41860
42336
|
0,
|
|
41861
42337
|
metricsBySection[0]?.pageContentHeightPx ?? fallbackMetrics.pageContentHeightPx
|
|
@@ -41919,7 +42395,8 @@ function buildDocumentPageNodeSegments2(model, pageContentHeightPx, pageContentW
|
|
|
41919
42395
|
const keepLinesOverflowSplit = node.style?.keepLines === true && paragraphTooTallForSinglePage;
|
|
41920
42396
|
const keepNextOverflowSplit = node.style?.keepNext === true && paragraphTooTallForSinglePage;
|
|
41921
42397
|
const forceOverflowSplit = keepLinesOverflowSplit || keepNextOverflowSplit;
|
|
41922
|
-
|
|
42398
|
+
const nodeIsWithinCommittedKeepNextChain = nodeIndex <= committedKeepNextChainEndNodeIndex;
|
|
42399
|
+
if (forceOverflowSplit && !nodeIsWithinCommittedKeepNextChain && pageConsumedHeightPx > 0 && currentPageSegments.length > 0) {
|
|
41923
42400
|
startNextPage();
|
|
41924
42401
|
pageConsumedHeightPx = 0;
|
|
41925
42402
|
previousParagraphAfterPx = 0;
|
|
@@ -42069,7 +42546,8 @@ function buildDocumentPageNodeSegments2(model, pageContentHeightPx, pageContentW
|
|
|
42069
42546
|
continue;
|
|
42070
42547
|
}
|
|
42071
42548
|
let requiredHeightPx = collapsedNodeHeightPx;
|
|
42072
|
-
|
|
42549
|
+
let keepNextChainEndNodeIndex = -1;
|
|
42550
|
+
if (node.style?.keepNext === true && !nodeIsWithinCommittedKeepNextChain && callbacks.paragraphHasVisibleText(node)) {
|
|
42073
42551
|
let chainCursor = nodeIndex;
|
|
42074
42552
|
let chainPreviousParagraphAfterPx = afterSpacingPx;
|
|
42075
42553
|
while (chainCursor < model.nodes.length - 1) {
|
|
@@ -42127,6 +42605,7 @@ function buildDocumentPageNodeSegments2(model, pageContentHeightPx, pageContentW
|
|
|
42127
42605
|
);
|
|
42128
42606
|
chainPreviousParagraphAfterPx = paragraphAfterSpacingPx2(nextChainNode);
|
|
42129
42607
|
}
|
|
42608
|
+
keepNextChainEndNodeIndex = chainCursor;
|
|
42130
42609
|
}
|
|
42131
42610
|
const remainingHeightPx = currentPageContentHeightPx - pageConsumedHeightPx;
|
|
42132
42611
|
if (pageConsumedHeightPx > 0 && requiredHeightPx > remainingHeightPx + pageOverflowTolerancePx) {
|
|
@@ -42138,6 +42617,9 @@ function buildDocumentPageNodeSegments2(model, pageContentHeightPx, pageContentW
|
|
|
42138
42617
|
nodeMetrics.pageContentHeightPx
|
|
42139
42618
|
);
|
|
42140
42619
|
}
|
|
42620
|
+
if (pageConsumedHeightPx === 0 && keepNextChainEndNodeIndex > nodeIndex) {
|
|
42621
|
+
committedKeepNextChainEndNodeIndex = keepNextChainEndNodeIndex;
|
|
42622
|
+
}
|
|
42141
42623
|
currentPageSegments.push({ nodeIndex });
|
|
42142
42624
|
const effectiveNodeHeightPx = pageConsumedHeightPx > 0 ? collapsedNodeHeightPx : rawNodeHeightPx;
|
|
42143
42625
|
pageConsumedHeightPx += effectiveNodeHeightPx;
|
|
@@ -42868,6 +43350,7 @@ export {
|
|
|
42868
43350
|
defaultStarterModel,
|
|
42869
43351
|
duplicateParagraph,
|
|
42870
43352
|
getPart,
|
|
43353
|
+
initWasm,
|
|
42871
43354
|
insertParagraph,
|
|
42872
43355
|
layoutDocument,
|
|
42873
43356
|
modelToDocumentXml,
|
|
@@ -42909,6 +43392,7 @@ export {
|
|
|
42909
43392
|
setParagraphHeading,
|
|
42910
43393
|
setRunColor,
|
|
42911
43394
|
setRunHighlight,
|
|
43395
|
+
setWasmSource,
|
|
42912
43396
|
splitParagraphChildrenAtTextOffsets,
|
|
42913
43397
|
toggleRunStyleFlag,
|
|
42914
43398
|
updateParagraphText,
|