@extend-ai/react-docx 0.7.0-alpha.2 → 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/dist/docx_wasm_bg.wasm +0 -0
- package/dist/index.cjs +723 -346
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +721 -346
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -2906,16 +2906,17 @@ function shouldAllowStoredPageCountReduction(options) {
|
|
|
2906
2906
|
if (targetPageCount >= estimatedPageCount) {
|
|
2907
2907
|
return true;
|
|
2908
2908
|
}
|
|
2909
|
+
const renderedBreakHintPageCount = Number.isFinite(
|
|
2910
|
+
options.renderedBreakHintPageCount
|
|
2911
|
+
) ? Math.max(1, Math.round(options.renderedBreakHintPageCount)) : void 0;
|
|
2912
|
+
const renderedBreakHintsSupportTarget = options.hasLastRenderedPageBreakHints === true && renderedBreakHintPageCount !== void 0 && targetPageCount >= renderedBreakHintPageCount;
|
|
2909
2913
|
if (options.hasMeasuredBodyFooterOverlap === true) {
|
|
2910
|
-
return
|
|
2914
|
+
return renderedBreakHintsSupportTarget;
|
|
2911
2915
|
}
|
|
2912
2916
|
if (options.hasLastRenderedPageBreakHints !== true) {
|
|
2913
2917
|
return true;
|
|
2914
2918
|
}
|
|
2915
|
-
|
|
2916
|
-
options.renderedBreakHintPageCount
|
|
2917
|
-
) ? Math.max(1, Math.round(options.renderedBreakHintPageCount)) : void 0;
|
|
2918
|
-
return renderedBreakHintPageCount !== void 0 && targetPageCount >= renderedBreakHintPageCount;
|
|
2919
|
+
return renderedBreakHintsSupportTarget;
|
|
2919
2920
|
}
|
|
2920
2921
|
function shouldLatchMeasuredBodyFooterOverlap(options) {
|
|
2921
2922
|
if (options.measuredBodyFooterOverlap !== true) {
|
|
@@ -4022,6 +4023,425 @@ function sliceLayoutToLineRange(layout, startLineIndex, endLineIndex) {
|
|
|
4022
4023
|
};
|
|
4023
4024
|
}
|
|
4024
4025
|
|
|
4026
|
+
// src/content-signature.ts
|
|
4027
|
+
init_cjs_shims();
|
|
4028
|
+
var FNV_OFFSET_BASIS = 2166136261;
|
|
4029
|
+
var FNV_PRIME = 16777619;
|
|
4030
|
+
var LONG_STRING_SAMPLE_LENGTH = 64;
|
|
4031
|
+
var LONG_STRING_THRESHOLD = 256;
|
|
4032
|
+
function fnv1aAppend(hash, text) {
|
|
4033
|
+
let next = hash;
|
|
4034
|
+
for (let index = 0; index < text.length; index += 1) {
|
|
4035
|
+
next ^= text.charCodeAt(index);
|
|
4036
|
+
next = Math.imul(next, FNV_PRIME);
|
|
4037
|
+
}
|
|
4038
|
+
return next >>> 0;
|
|
4039
|
+
}
|
|
4040
|
+
function fnv1aAppendString(hash, value) {
|
|
4041
|
+
if (value.length <= LONG_STRING_THRESHOLD) {
|
|
4042
|
+
return fnv1aAppend(fnv1aAppend(hash, `${value.length}:`), value);
|
|
4043
|
+
}
|
|
4044
|
+
const head = value.slice(0, LONG_STRING_SAMPLE_LENGTH);
|
|
4045
|
+
const middleIndex = Math.floor(value.length / 2);
|
|
4046
|
+
const middle = value.slice(
|
|
4047
|
+
middleIndex,
|
|
4048
|
+
middleIndex + LONG_STRING_SAMPLE_LENGTH
|
|
4049
|
+
);
|
|
4050
|
+
const tail = value.slice(value.length - LONG_STRING_SAMPLE_LENGTH);
|
|
4051
|
+
let next = fnv1aAppend(hash, `${value.length}:`);
|
|
4052
|
+
next = fnv1aAppend(next, head);
|
|
4053
|
+
next = fnv1aAppend(next, middle);
|
|
4054
|
+
return fnv1aAppend(next, tail);
|
|
4055
|
+
}
|
|
4056
|
+
function fnv1aAppendValue(hash, value) {
|
|
4057
|
+
if (value === null) {
|
|
4058
|
+
return fnv1aAppend(hash, "~n");
|
|
4059
|
+
}
|
|
4060
|
+
switch (typeof value) {
|
|
4061
|
+
case "undefined":
|
|
4062
|
+
return fnv1aAppend(hash, "~u");
|
|
4063
|
+
case "string":
|
|
4064
|
+
return fnv1aAppendString(fnv1aAppend(hash, "~s"), value);
|
|
4065
|
+
case "number":
|
|
4066
|
+
return fnv1aAppend(hash, `~#${value}`);
|
|
4067
|
+
case "boolean":
|
|
4068
|
+
return fnv1aAppend(hash, value ? "~t" : "~f");
|
|
4069
|
+
case "object":
|
|
4070
|
+
break;
|
|
4071
|
+
default:
|
|
4072
|
+
return fnv1aAppend(hash, "~x");
|
|
4073
|
+
}
|
|
4074
|
+
if (Array.isArray(value)) {
|
|
4075
|
+
let next2 = fnv1aAppend(hash, `~a${value.length}`);
|
|
4076
|
+
for (const entry of value) {
|
|
4077
|
+
next2 = fnv1aAppendValue(next2, entry);
|
|
4078
|
+
}
|
|
4079
|
+
return next2;
|
|
4080
|
+
}
|
|
4081
|
+
if (ArrayBuffer.isView(value) || value instanceof ArrayBuffer) {
|
|
4082
|
+
const byteLength = value instanceof ArrayBuffer ? value.byteLength : value.byteLength;
|
|
4083
|
+
return fnv1aAppend(hash, `~b${byteLength}`);
|
|
4084
|
+
}
|
|
4085
|
+
let next = fnv1aAppend(hash, "~o");
|
|
4086
|
+
for (const key of Object.keys(value)) {
|
|
4087
|
+
const entry = value[key];
|
|
4088
|
+
if (entry === void 0) {
|
|
4089
|
+
continue;
|
|
4090
|
+
}
|
|
4091
|
+
next = fnv1aAppend(next, key);
|
|
4092
|
+
next = fnv1aAppendValue(next, entry);
|
|
4093
|
+
}
|
|
4094
|
+
return next;
|
|
4095
|
+
}
|
|
4096
|
+
function contentHash(value) {
|
|
4097
|
+
return fnv1aAppendValue(FNV_OFFSET_BASIS, value).toString(36);
|
|
4098
|
+
}
|
|
4099
|
+
var nodeSignatureCache = /* @__PURE__ */ new WeakMap();
|
|
4100
|
+
function docNodeContentSignature(node) {
|
|
4101
|
+
if (typeof node !== "object" || node === null) {
|
|
4102
|
+
return contentHash(node);
|
|
4103
|
+
}
|
|
4104
|
+
const cached = nodeSignatureCache.get(node);
|
|
4105
|
+
if (cached !== void 0) {
|
|
4106
|
+
return cached;
|
|
4107
|
+
}
|
|
4108
|
+
const signature = contentHash(node);
|
|
4109
|
+
nodeSignatureCache.set(node, signature);
|
|
4110
|
+
return signature;
|
|
4111
|
+
}
|
|
4112
|
+
var metadataSignatureCache = /* @__PURE__ */ new WeakMap();
|
|
4113
|
+
function docModelThumbnailMetadataSignature(metadata) {
|
|
4114
|
+
const cached = metadataSignatureCache.get(metadata);
|
|
4115
|
+
if (cached !== void 0) {
|
|
4116
|
+
return cached;
|
|
4117
|
+
}
|
|
4118
|
+
const relevant = metadata;
|
|
4119
|
+
let hash = FNV_OFFSET_BASIS;
|
|
4120
|
+
hash = fnv1aAppendValue(hash, relevant.sections);
|
|
4121
|
+
hash = fnv1aAppendValue(hash, relevant.headerSections);
|
|
4122
|
+
hash = fnv1aAppendValue(hash, relevant.footerSections);
|
|
4123
|
+
hash = fnv1aAppendValue(hash, relevant.numberingDefinitions);
|
|
4124
|
+
hash = fnv1aAppendValue(hash, relevant.footnotes);
|
|
4125
|
+
hash = fnv1aAppendValue(hash, relevant.endnotes);
|
|
4126
|
+
hash = fnv1aAppendValue(hash, relevant.documentBackgroundColor);
|
|
4127
|
+
hash = fnv1aAppendValue(hash, relevant.compatibility);
|
|
4128
|
+
const signature = (hash >>> 0).toString(36);
|
|
4129
|
+
metadataSignatureCache.set(metadata, signature);
|
|
4130
|
+
return signature;
|
|
4131
|
+
}
|
|
4132
|
+
|
|
4133
|
+
// src/thumbnail-raster.ts
|
|
4134
|
+
init_cjs_shims();
|
|
4135
|
+
var DOCX_THUMBNAIL_EXCLUDE_ATTRIBUTE = "data-docx-thumbnail-exclude";
|
|
4136
|
+
var THUMBNAIL_EXCLUDED_CLONE_SELECTOR = [
|
|
4137
|
+
`[${DOCX_THUMBNAIL_EXCLUDE_ATTRIBUTE}="true"]`,
|
|
4138
|
+
"textarea",
|
|
4139
|
+
'[data-image-resize-handle="true"]',
|
|
4140
|
+
'[data-docx-table-move-handle="true"]'
|
|
4141
|
+
].join(",");
|
|
4142
|
+
var THUMBNAIL_IMAGE_DOWNSCALE_MIN_DATA_URI_LENGTH = 32768;
|
|
4143
|
+
var THUMBNAIL_IMAGE_DOWNSCALE_MAX_DIMENSION_PX = 512;
|
|
4144
|
+
var THUMBNAIL_IMAGE_JPEG_QUALITY = 0.78;
|
|
4145
|
+
function thumbnailSvgDataUri(svg) {
|
|
4146
|
+
return `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg)}`;
|
|
4147
|
+
}
|
|
4148
|
+
function thumbnailImageSourceQualifiesForDownscale(src) {
|
|
4149
|
+
return src.length >= THUMBNAIL_IMAGE_DOWNSCALE_MIN_DATA_URI_LENGTH && src.startsWith("data:image/") && !src.startsWith("data:image/svg");
|
|
4150
|
+
}
|
|
4151
|
+
async function loadThumbnailImage(src) {
|
|
4152
|
+
const image = new Image();
|
|
4153
|
+
image.decoding = "async";
|
|
4154
|
+
const loaded = new Promise((resolve, reject) => {
|
|
4155
|
+
image.onload = () => resolve(image);
|
|
4156
|
+
image.onerror = () => {
|
|
4157
|
+
reject(new Error("Failed to decode DOCX thumbnail image."));
|
|
4158
|
+
};
|
|
4159
|
+
});
|
|
4160
|
+
image.src = src;
|
|
4161
|
+
if (typeof image.decode === "function") {
|
|
4162
|
+
try {
|
|
4163
|
+
await image.decode();
|
|
4164
|
+
return image;
|
|
4165
|
+
} catch {
|
|
4166
|
+
}
|
|
4167
|
+
}
|
|
4168
|
+
return loaded;
|
|
4169
|
+
}
|
|
4170
|
+
var downscaledThumbnailImageCache = /* @__PURE__ */ new Map();
|
|
4171
|
+
async function downscaleThumbnailImageDataUri(src) {
|
|
4172
|
+
if (typeof document === "undefined") {
|
|
4173
|
+
return void 0;
|
|
4174
|
+
}
|
|
4175
|
+
const image = await loadThumbnailImage(src);
|
|
4176
|
+
const naturalWidth = image.naturalWidth || image.width;
|
|
4177
|
+
const naturalHeight = image.naturalHeight || image.height;
|
|
4178
|
+
if (!naturalWidth || !naturalHeight) {
|
|
4179
|
+
return void 0;
|
|
4180
|
+
}
|
|
4181
|
+
const scale = THUMBNAIL_IMAGE_DOWNSCALE_MAX_DIMENSION_PX / Math.max(naturalWidth, naturalHeight);
|
|
4182
|
+
if (scale >= 1) {
|
|
4183
|
+
return void 0;
|
|
4184
|
+
}
|
|
4185
|
+
const canvas = document.createElement("canvas");
|
|
4186
|
+
canvas.width = Math.max(1, Math.round(naturalWidth * scale));
|
|
4187
|
+
canvas.height = Math.max(1, Math.round(naturalHeight * scale));
|
|
4188
|
+
const context = canvas.getContext("2d");
|
|
4189
|
+
if (!context) {
|
|
4190
|
+
return void 0;
|
|
4191
|
+
}
|
|
4192
|
+
context.imageSmoothingEnabled = true;
|
|
4193
|
+
context.imageSmoothingQuality = "high";
|
|
4194
|
+
context.drawImage(image, 0, 0, canvas.width, canvas.height);
|
|
4195
|
+
const sourceIsJpeg = src.startsWith("data:image/jpeg") || src.startsWith("data:image/jpg");
|
|
4196
|
+
const downscaled = sourceIsJpeg ? canvas.toDataURL("image/jpeg", THUMBNAIL_IMAGE_JPEG_QUALITY) : canvas.toDataURL("image/png");
|
|
4197
|
+
return downscaled.length < src.length ? downscaled : void 0;
|
|
4198
|
+
}
|
|
4199
|
+
function getDownscaledThumbnailImageDataUri(src) {
|
|
4200
|
+
const cached = downscaledThumbnailImageCache.get(src);
|
|
4201
|
+
if (cached) {
|
|
4202
|
+
return cached;
|
|
4203
|
+
}
|
|
4204
|
+
const pending = downscaleThumbnailImageDataUri(src).catch(() => void 0);
|
|
4205
|
+
downscaledThumbnailImageCache.set(src, pending);
|
|
4206
|
+
return pending;
|
|
4207
|
+
}
|
|
4208
|
+
async function buildDocxThumbnailSvgMarkup(params) {
|
|
4209
|
+
const { pageElement, sourceWidthPx, sourceHeightPx, widthPx, heightPx } = params;
|
|
4210
|
+
const clone = pageElement.cloneNode(true);
|
|
4211
|
+
clone.querySelectorAll(THUMBNAIL_EXCLUDED_CLONE_SELECTOR).forEach((excluded) => {
|
|
4212
|
+
excluded.remove();
|
|
4213
|
+
});
|
|
4214
|
+
const cloneImages = Array.from(clone.querySelectorAll("img"));
|
|
4215
|
+
await Promise.all(
|
|
4216
|
+
cloneImages.map(async (cloneImage) => {
|
|
4217
|
+
const src = cloneImage.getAttribute("src");
|
|
4218
|
+
if (!src || !thumbnailImageSourceQualifiesForDownscale(src)) {
|
|
4219
|
+
return;
|
|
4220
|
+
}
|
|
4221
|
+
const downscaled = await getDownscaledThumbnailImageDataUri(src);
|
|
4222
|
+
if (downscaled) {
|
|
4223
|
+
cloneImage.setAttribute("src", downscaled);
|
|
4224
|
+
}
|
|
4225
|
+
})
|
|
4226
|
+
);
|
|
4227
|
+
const scaleX = widthPx / sourceWidthPx;
|
|
4228
|
+
const scaleY = heightPx / sourceHeightPx;
|
|
4229
|
+
const serializedPage = new XMLSerializer().serializeToString(clone);
|
|
4230
|
+
return `
|
|
4231
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="${widthPx}" height="${heightPx}" viewBox="0 0 ${widthPx} ${heightPx}">
|
|
4232
|
+
<foreignObject x="0" y="0" width="100%" height="100%">
|
|
4233
|
+
<div xmlns="http://www.w3.org/1999/xhtml" style="width:${widthPx}px;height:${heightPx}px;overflow:hidden;">
|
|
4234
|
+
<div style="width:${sourceWidthPx}px;height:${sourceHeightPx}px;transform-origin:top left;transform:scale(${scaleX}, ${scaleY});">
|
|
4235
|
+
${serializedPage}
|
|
4236
|
+
</div>
|
|
4237
|
+
</div>
|
|
4238
|
+
</foreignObject>
|
|
4239
|
+
</svg>
|
|
4240
|
+
`;
|
|
4241
|
+
}
|
|
4242
|
+
async function rasterizeDocxThumbnailSurface(params) {
|
|
4243
|
+
if (typeof window === "undefined" || typeof XMLSerializer === "undefined") {
|
|
4244
|
+
throw new Error("DOCX thumbnails require a browser environment.");
|
|
4245
|
+
}
|
|
4246
|
+
const safeSourceWidthPx = Math.max(1, Math.round(params.sourceWidthPx));
|
|
4247
|
+
const safeSourceHeightPx = Math.max(1, Math.round(params.sourceHeightPx));
|
|
4248
|
+
const svgMarkup = await buildDocxThumbnailSvgMarkup({
|
|
4249
|
+
pageElement: params.pageElement,
|
|
4250
|
+
sourceWidthPx: safeSourceWidthPx,
|
|
4251
|
+
sourceHeightPx: safeSourceHeightPx,
|
|
4252
|
+
widthPx: params.widthPx,
|
|
4253
|
+
heightPx: params.heightPx
|
|
4254
|
+
});
|
|
4255
|
+
const image = await loadThumbnailImage(thumbnailSvgDataUri(svgMarkup));
|
|
4256
|
+
const surface = document.createElement("canvas");
|
|
4257
|
+
surface.width = Math.max(1, Math.round(params.pixelWidthPx));
|
|
4258
|
+
surface.height = Math.max(1, Math.round(params.pixelHeightPx));
|
|
4259
|
+
const context = surface.getContext("2d");
|
|
4260
|
+
if (!context) {
|
|
4261
|
+
throw new Error("2D canvas context is unavailable for DOCX thumbnails.");
|
|
4262
|
+
}
|
|
4263
|
+
context.imageSmoothingEnabled = true;
|
|
4264
|
+
context.imageSmoothingQuality = "high";
|
|
4265
|
+
context.drawImage(image, 0, 0, surface.width, surface.height);
|
|
4266
|
+
return surface;
|
|
4267
|
+
}
|
|
4268
|
+
function blitDocxThumbnailSurface(surface, canvas, resolution) {
|
|
4269
|
+
canvas.width = Math.max(1, Math.round(resolution.pixelWidthPx));
|
|
4270
|
+
canvas.height = Math.max(1, Math.round(resolution.pixelHeightPx));
|
|
4271
|
+
canvas.style.width = `${Math.max(1, Math.round(resolution.widthPx))}px`;
|
|
4272
|
+
canvas.style.height = `${Math.max(1, Math.round(resolution.heightPx))}px`;
|
|
4273
|
+
const context = canvas.getContext("2d");
|
|
4274
|
+
if (!context) {
|
|
4275
|
+
throw new Error("2D canvas context is unavailable for DOCX thumbnails.");
|
|
4276
|
+
}
|
|
4277
|
+
context.setTransform(1, 0, 0, 1, 0, 0);
|
|
4278
|
+
context.clearRect(0, 0, canvas.width, canvas.height);
|
|
4279
|
+
context.drawImage(surface, 0, 0, canvas.width, canvas.height);
|
|
4280
|
+
}
|
|
4281
|
+
var DocxThumbnailSurfaceCache = class {
|
|
4282
|
+
constructor(maxEntries) {
|
|
4283
|
+
this.maxEntries = maxEntries;
|
|
4284
|
+
}
|
|
4285
|
+
entries = /* @__PURE__ */ new Map();
|
|
4286
|
+
get size() {
|
|
4287
|
+
return this.entries.size;
|
|
4288
|
+
}
|
|
4289
|
+
get(key) {
|
|
4290
|
+
const value = this.entries.get(key);
|
|
4291
|
+
if (value === void 0) {
|
|
4292
|
+
return void 0;
|
|
4293
|
+
}
|
|
4294
|
+
this.entries.delete(key);
|
|
4295
|
+
this.entries.set(key, value);
|
|
4296
|
+
return value;
|
|
4297
|
+
}
|
|
4298
|
+
set(key, value) {
|
|
4299
|
+
this.entries.delete(key);
|
|
4300
|
+
this.entries.set(key, value);
|
|
4301
|
+
while (this.entries.size > this.maxEntries) {
|
|
4302
|
+
const oldestKey = this.entries.keys().next().value;
|
|
4303
|
+
if (oldestKey === void 0) {
|
|
4304
|
+
break;
|
|
4305
|
+
}
|
|
4306
|
+
this.entries.delete(oldestKey);
|
|
4307
|
+
}
|
|
4308
|
+
}
|
|
4309
|
+
clear() {
|
|
4310
|
+
this.entries.clear();
|
|
4311
|
+
}
|
|
4312
|
+
};
|
|
4313
|
+
var IDLE_TASK_TIMEOUT_MS = 300;
|
|
4314
|
+
function defaultScheduleTask(callback) {
|
|
4315
|
+
const idleWindow = typeof window === "undefined" ? void 0 : window;
|
|
4316
|
+
if (!idleWindow || typeof idleWindow.requestIdleCallback !== "function") {
|
|
4317
|
+
setTimeout(callback, 16);
|
|
4318
|
+
return;
|
|
4319
|
+
}
|
|
4320
|
+
let invoked = false;
|
|
4321
|
+
const runOnce = () => {
|
|
4322
|
+
if (invoked) {
|
|
4323
|
+
return;
|
|
4324
|
+
}
|
|
4325
|
+
invoked = true;
|
|
4326
|
+
callback();
|
|
4327
|
+
};
|
|
4328
|
+
const idleHandle = idleWindow.requestIdleCallback(runOnce, {
|
|
4329
|
+
timeout: IDLE_TASK_TIMEOUT_MS
|
|
4330
|
+
});
|
|
4331
|
+
setTimeout(() => {
|
|
4332
|
+
if (invoked) {
|
|
4333
|
+
return;
|
|
4334
|
+
}
|
|
4335
|
+
if (typeof idleWindow.cancelIdleCallback === "function") {
|
|
4336
|
+
idleWindow.cancelIdleCallback(idleHandle);
|
|
4337
|
+
}
|
|
4338
|
+
runOnce();
|
|
4339
|
+
}, IDLE_TASK_TIMEOUT_MS + 50);
|
|
4340
|
+
}
|
|
4341
|
+
function defaultScheduleDelayed(callback, delayMs) {
|
|
4342
|
+
setTimeout(callback, delayMs);
|
|
4343
|
+
}
|
|
4344
|
+
var SerialIdleTaskQueue = class {
|
|
4345
|
+
pending = [];
|
|
4346
|
+
lastRunAtByKey = /* @__PURE__ */ new Map();
|
|
4347
|
+
scheduleTask;
|
|
4348
|
+
scheduleDelayed;
|
|
4349
|
+
minTaskIntervalMs;
|
|
4350
|
+
now;
|
|
4351
|
+
pumpScheduled = false;
|
|
4352
|
+
running = false;
|
|
4353
|
+
constructor(options) {
|
|
4354
|
+
this.scheduleTask = options?.scheduleTask ?? defaultScheduleTask;
|
|
4355
|
+
this.scheduleDelayed = options?.scheduleDelayed ?? defaultScheduleDelayed;
|
|
4356
|
+
this.minTaskIntervalMs = Math.max(0, options?.minTaskIntervalMs ?? 0);
|
|
4357
|
+
this.now = options?.now ?? (() => Date.now());
|
|
4358
|
+
}
|
|
4359
|
+
get pendingCount() {
|
|
4360
|
+
return this.pending.length;
|
|
4361
|
+
}
|
|
4362
|
+
enqueue(key, run) {
|
|
4363
|
+
return new Promise((resolve) => {
|
|
4364
|
+
const existing = this.pending.find((entry) => entry.key === key);
|
|
4365
|
+
if (existing) {
|
|
4366
|
+
existing.run = run;
|
|
4367
|
+
existing.resolvers.push(resolve);
|
|
4368
|
+
} else {
|
|
4369
|
+
this.pending.push({ key, run, resolvers: [resolve] });
|
|
4370
|
+
}
|
|
4371
|
+
this.schedulePump();
|
|
4372
|
+
});
|
|
4373
|
+
}
|
|
4374
|
+
/** Drops all queued tasks, resolving their waiters without running them. */
|
|
4375
|
+
clear() {
|
|
4376
|
+
const dropped = this.pending.splice(0, this.pending.length);
|
|
4377
|
+
this.lastRunAtByKey.clear();
|
|
4378
|
+
dropped.forEach((entry) => {
|
|
4379
|
+
entry.resolvers.forEach((resolveEntry) => {
|
|
4380
|
+
resolveEntry();
|
|
4381
|
+
});
|
|
4382
|
+
});
|
|
4383
|
+
}
|
|
4384
|
+
schedulePump() {
|
|
4385
|
+
if (this.pumpScheduled || this.running || this.pending.length === 0) {
|
|
4386
|
+
return;
|
|
4387
|
+
}
|
|
4388
|
+
this.pumpScheduled = true;
|
|
4389
|
+
this.scheduleTask(() => {
|
|
4390
|
+
this.pumpScheduled = false;
|
|
4391
|
+
void this.runNext();
|
|
4392
|
+
});
|
|
4393
|
+
}
|
|
4394
|
+
takeNextEligibleEntry() {
|
|
4395
|
+
if (this.pending.length === 0) {
|
|
4396
|
+
return void 0;
|
|
4397
|
+
}
|
|
4398
|
+
const now = this.now();
|
|
4399
|
+
let earliestWaitMs;
|
|
4400
|
+
for (let index = 0; index < this.pending.length; index += 1) {
|
|
4401
|
+
const candidate = this.pending[index];
|
|
4402
|
+
if (!candidate) {
|
|
4403
|
+
continue;
|
|
4404
|
+
}
|
|
4405
|
+
const lastRunAt = this.lastRunAtByKey.get(candidate.key);
|
|
4406
|
+
const waitMs = lastRunAt === void 0 ? 0 : lastRunAt + this.minTaskIntervalMs - now;
|
|
4407
|
+
if (waitMs <= 0) {
|
|
4408
|
+
this.pending.splice(index, 1);
|
|
4409
|
+
return { entry: candidate };
|
|
4410
|
+
}
|
|
4411
|
+
earliestWaitMs = earliestWaitMs === void 0 ? waitMs : Math.min(earliestWaitMs, waitMs);
|
|
4412
|
+
}
|
|
4413
|
+
return earliestWaitMs === void 0 ? void 0 : { retryDelayMs: earliestWaitMs };
|
|
4414
|
+
}
|
|
4415
|
+
async runNext() {
|
|
4416
|
+
if (this.running) {
|
|
4417
|
+
return;
|
|
4418
|
+
}
|
|
4419
|
+
const next = this.takeNextEligibleEntry();
|
|
4420
|
+
if (!next) {
|
|
4421
|
+
return;
|
|
4422
|
+
}
|
|
4423
|
+
if (!("entry" in next)) {
|
|
4424
|
+
this.scheduleDelayed(() => {
|
|
4425
|
+
this.schedulePump();
|
|
4426
|
+
}, next.retryDelayMs);
|
|
4427
|
+
return;
|
|
4428
|
+
}
|
|
4429
|
+
this.running = true;
|
|
4430
|
+
const { entry } = next;
|
|
4431
|
+
try {
|
|
4432
|
+
await entry.run();
|
|
4433
|
+
} catch {
|
|
4434
|
+
} finally {
|
|
4435
|
+
this.lastRunAtByKey.set(entry.key, this.now());
|
|
4436
|
+
this.running = false;
|
|
4437
|
+
entry.resolvers.forEach((resolveEntry) => {
|
|
4438
|
+
resolveEntry();
|
|
4439
|
+
});
|
|
4440
|
+
this.schedulePump();
|
|
4441
|
+
}
|
|
4442
|
+
}
|
|
4443
|
+
};
|
|
4444
|
+
|
|
4025
4445
|
// src/editor.tsx
|
|
4026
4446
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
4027
4447
|
var HIGHLIGHT_TO_CSS = {
|
|
@@ -4118,6 +4538,9 @@ var DEFAULT_PARAGRAPH_LINE_MULTIPLE = 1;
|
|
|
4118
4538
|
var WORD_SINGLE_LINE_AUTO_SCALE = 0.88;
|
|
4119
4539
|
var WORD_SINGLE_LINE_AUTO_SCALE_SANS = 0.9;
|
|
4120
4540
|
var WORD_SINGLE_LINE_AUTO_SCALE_SERIF = 1.08;
|
|
4541
|
+
var WORD_EMPTY_PARAGRAPH_LINE_SCALE = 1.21;
|
|
4542
|
+
var WORD_EMPTY_PARAGRAPH_LINE_SCALE_SERIF = 1.15;
|
|
4543
|
+
var WORD_EMPTY_PARAGRAPH_LINE_SCALE_SANS = 1.15;
|
|
4121
4544
|
var WORD_AUTO_LINE_SCALE_BLEND_END_MULTIPLE = 1.08;
|
|
4122
4545
|
var MIN_AUTO_LINE_MULTIPLE = 0.1;
|
|
4123
4546
|
var MIN_PARAGRAPH_LINE_HEIGHT_PX = 14;
|
|
@@ -4162,7 +4585,6 @@ var TEXT_MEASURE_CACHE_MAX_ENTRIES = 12e3;
|
|
|
4162
4585
|
var DEFAULT_TAB_STOP_PX = 48;
|
|
4163
4586
|
var TAB_LEADER_ZONE_GAP_PX = 20;
|
|
4164
4587
|
var EMPTY_PARAGRAPH_EXTRA_HEIGHT_PX = 0;
|
|
4165
|
-
var LEADING_COVER_SPACER_EXTRA_HEIGHT_PX = 2;
|
|
4166
4588
|
var PARAGRAPH_SEGMENT_TOP_BLEED_PX = 22;
|
|
4167
4589
|
var PARAGRAPH_SEGMENT_DESCENDER_BLEED_PX = 6;
|
|
4168
4590
|
var PARAGRAPH_SEGMENT_VISUAL_SAFETY_PX = 24;
|
|
@@ -6682,19 +7104,6 @@ function floatingTextBoxVisibleTextFromImage(image) {
|
|
|
6682
7104
|
const normalized = normalizeFloatingTextBoxComparisonText(text);
|
|
6683
7105
|
return normalized.length > 0 ? normalized : void 0;
|
|
6684
7106
|
}
|
|
6685
|
-
function absoluteFloatingTextBearingTextBoxFootprintPx(image) {
|
|
6686
|
-
const floating = image.floating;
|
|
6687
|
-
if (!shouldRenderAbsoluteFloatingImage(image) || !floating || image.syntheticTextBox !== true || syntheticTextBoxContainsPictureLayer(image) || !floatingTextBoxVisibleTextFromImage(image)) {
|
|
6688
|
-
return 0;
|
|
6689
|
-
}
|
|
6690
|
-
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;
|
|
6691
|
-
const distTPx = Math.max(0, Math.round(floating.distTPx ?? 0));
|
|
6692
|
-
const distBPx = Math.max(0, Math.round(floating.distBPx ?? 0));
|
|
6693
|
-
return Math.max(
|
|
6694
|
-
MIN_PARAGRAPH_LINE_HEIGHT_PX,
|
|
6695
|
-
imageHeightPx + distTPx + distBPx
|
|
6696
|
-
);
|
|
6697
|
-
}
|
|
6698
7107
|
function paragraphVisibleTextIsOnlyAbsoluteFloatingTextBoxContent(paragraph) {
|
|
6699
7108
|
if (!paragraphHasVisibleText2(paragraph) || paragraphHasFormField2(paragraph)) {
|
|
6700
7109
|
return false;
|
|
@@ -6727,29 +7136,9 @@ function paragraphHasOnlyWhitespaceText(paragraph) {
|
|
|
6727
7136
|
return child.text.replace(/[\s\u00a0]+/g, "").length === 0;
|
|
6728
7137
|
});
|
|
6729
7138
|
}
|
|
6730
|
-
function paragraphHasActiveNumbering(paragraph) {
|
|
6731
|
-
const numbering = paragraph.style?.numbering;
|
|
6732
|
-
return Boolean(
|
|
6733
|
-
numbering && Number.isFinite(numbering.numId) && Math.round(numbering.numId) > 0
|
|
6734
|
-
);
|
|
6735
|
-
}
|
|
6736
7139
|
function paragraphContainsSectionBreakProperties(paragraph) {
|
|
6737
7140
|
return /<w:sectPr\b/i.test(paragraph.sourceXml ?? "");
|
|
6738
7141
|
}
|
|
6739
|
-
function paragraphTextBearingAbsoluteFloatingTextBoxFootprintPx(paragraph) {
|
|
6740
|
-
if (paragraphHasVisibleText2(paragraph) || paragraphHasFormField2(paragraph) || paragraphContainsSectionBreakProperties(paragraph)) {
|
|
6741
|
-
return 0;
|
|
6742
|
-
}
|
|
6743
|
-
return paragraph.children.reduce((largest, child) => {
|
|
6744
|
-
if (child.type !== "image") {
|
|
6745
|
-
return largest;
|
|
6746
|
-
}
|
|
6747
|
-
return Math.max(
|
|
6748
|
-
largest,
|
|
6749
|
-
absoluteFloatingTextBearingTextBoxFootprintPx(child)
|
|
6750
|
-
);
|
|
6751
|
-
}, 0);
|
|
6752
|
-
}
|
|
6753
7142
|
function paragraphAbsoluteFloatingAnchorsDependOnParagraphFlow(paragraph) {
|
|
6754
7143
|
return paragraph.children.some((child) => {
|
|
6755
7144
|
if (child.type !== "image" || !shouldRenderAbsoluteFloatingImage(child) || child.syntheticTextBox !== true || !floatingTextBoxVisibleTextFromImage(child) || child.floating?.behindDocument !== true) {
|
|
@@ -6841,21 +7230,6 @@ function paragraphParticipatesInLeadingCoverLayout(model, nodeIndex, pageContent
|
|
|
6841
7230
|
}
|
|
6842
7231
|
return sawLikelyCoverArtAnchor;
|
|
6843
7232
|
}
|
|
6844
|
-
function paragraphLikelyFullPageCoverFootprintPx(model, nodeIndex, paragraph, pageContentWidthPx, pageContentHeightPx) {
|
|
6845
|
-
if (!paragraphParticipatesInLeadingCoverLayout(
|
|
6846
|
-
model,
|
|
6847
|
-
nodeIndex,
|
|
6848
|
-
pageContentWidthPx,
|
|
6849
|
-
pageContentHeightPx
|
|
6850
|
-
) || !paragraphIsLikelyFullPageCoverArtAnchor(
|
|
6851
|
-
paragraph,
|
|
6852
|
-
pageContentWidthPx,
|
|
6853
|
-
pageContentHeightPx
|
|
6854
|
-
)) {
|
|
6855
|
-
return 0;
|
|
6856
|
-
}
|
|
6857
|
-
return Math.max(1, Math.round(pageContentHeightPx));
|
|
6858
|
-
}
|
|
6859
7233
|
function fullPageCoverImageRenderKey(nodeIndex, childIndex) {
|
|
6860
7234
|
return `${nodeIndex}:${childIndex}`;
|
|
6861
7235
|
}
|
|
@@ -6894,71 +7268,6 @@ function fullPageCoverAbsoluteFloatingImageStyle(image, layout, options) {
|
|
|
6894
7268
|
zIndex: floating?.behindDocument === true ? 0 : normalizedZIndex
|
|
6895
7269
|
};
|
|
6896
7270
|
}
|
|
6897
|
-
function paragraphActsAsLeadingCoverLayoutSpacer(model, nodeIndex, paragraph, pageContentWidthPx, pageContentHeightPx) {
|
|
6898
|
-
if (nodeIndex <= 0 || !paragraphHasOnlyWhitespaceText(paragraph) || paragraphHasExplicitPageBreak2(paragraph)) {
|
|
6899
|
-
return false;
|
|
6900
|
-
}
|
|
6901
|
-
if (paragraphHasActiveNumbering(paragraph)) {
|
|
6902
|
-
return false;
|
|
6903
|
-
}
|
|
6904
|
-
return paragraphParticipatesInLeadingCoverLayout(
|
|
6905
|
-
model,
|
|
6906
|
-
nodeIndex,
|
|
6907
|
-
pageContentWidthPx,
|
|
6908
|
-
pageContentHeightPx
|
|
6909
|
-
);
|
|
6910
|
-
}
|
|
6911
|
-
function paragraphActsAsLeadingCoverLayoutPreambleSpacer(model, nodeIndex, paragraph, pageContentWidthPx, pageContentHeightPx) {
|
|
6912
|
-
if (!paragraphHasOnlyWhitespaceText(paragraph) || paragraphHasExplicitPageBreak2(paragraph) || paragraphHasActiveNumbering(paragraph)) {
|
|
6913
|
-
return false;
|
|
6914
|
-
}
|
|
6915
|
-
const nextNode = model.nodes[nodeIndex + 1];
|
|
6916
|
-
if (!nextNode || nextNode.type !== "paragraph") {
|
|
6917
|
-
return false;
|
|
6918
|
-
}
|
|
6919
|
-
if (!paragraphParticipatesInLeadingCoverLayout(
|
|
6920
|
-
model,
|
|
6921
|
-
nodeIndex + 1,
|
|
6922
|
-
pageContentWidthPx,
|
|
6923
|
-
pageContentHeightPx
|
|
6924
|
-
)) {
|
|
6925
|
-
return false;
|
|
6926
|
-
}
|
|
6927
|
-
for (let probeIndex = nodeIndex - 1; probeIndex >= 0; probeIndex -= 1) {
|
|
6928
|
-
const previousNode = model.nodes[probeIndex];
|
|
6929
|
-
if (!previousNode || previousNode.type !== "paragraph") {
|
|
6930
|
-
return false;
|
|
6931
|
-
}
|
|
6932
|
-
if (paragraphHasOnlyWhitespaceText(previousNode)) {
|
|
6933
|
-
continue;
|
|
6934
|
-
}
|
|
6935
|
-
if (paragraphHasAbsoluteFloatingImage(previousNode)) {
|
|
6936
|
-
return false;
|
|
6937
|
-
}
|
|
6938
|
-
return !paragraphIsLikelyFullPageCoverArtAnchor(
|
|
6939
|
-
previousNode,
|
|
6940
|
-
pageContentWidthPx,
|
|
6941
|
-
pageContentHeightPx
|
|
6942
|
-
);
|
|
6943
|
-
}
|
|
6944
|
-
return true;
|
|
6945
|
-
}
|
|
6946
|
-
function paragraphStartsNewPageAfterLeadingCoverLayout(model, nodeIndex, paragraph, pageContentWidthPx, pageContentHeightPx) {
|
|
6947
|
-
if (nodeIndex <= 0 || !paragraphStartsNormalFlowContent(paragraph) || paragraphHasExplicitPageBreak2(paragraph) || paragraphHasPageBreakBefore2(paragraph)) {
|
|
6948
|
-
return false;
|
|
6949
|
-
}
|
|
6950
|
-
const previousNode = model.nodes[nodeIndex - 1];
|
|
6951
|
-
if (!previousNode || previousNode.type !== "paragraph") {
|
|
6952
|
-
return false;
|
|
6953
|
-
}
|
|
6954
|
-
return paragraphActsAsLeadingCoverLayoutSpacer(
|
|
6955
|
-
model,
|
|
6956
|
-
nodeIndex - 1,
|
|
6957
|
-
previousNode,
|
|
6958
|
-
pageContentWidthPx,
|
|
6959
|
-
pageContentHeightPx
|
|
6960
|
-
);
|
|
6961
|
-
}
|
|
6962
7271
|
function paragraphLooksLikeCheckboxChoiceRow(paragraph) {
|
|
6963
7272
|
if (paragraph.children.some((child) => child.type === "image")) {
|
|
6964
7273
|
return false;
|
|
@@ -7476,7 +7785,8 @@ function buildParagraphPretextLayoutSource(paragraph, options) {
|
|
|
7476
7785
|
let combinedText = "";
|
|
7477
7786
|
const paragraphBaseFontPx = paragraphBaseFontSizePx(paragraph);
|
|
7478
7787
|
const tabStopPositionsPx = options?.expandTabsForLayout ? resolveParagraphTabStopsPx(paragraph) : [];
|
|
7479
|
-
const
|
|
7788
|
+
const usesCheckboxRowTabFallback = paragraphLooksLikeCheckboxChoiceRow(paragraph);
|
|
7789
|
+
const fallbackTabWidthPx = usesCheckboxRowTabFallback ? checkboxChoiceRowTabWidthPx(paragraph) : DEFAULT_TAB_STOP_PX;
|
|
7480
7790
|
let approximateLineWidthPx = 0;
|
|
7481
7791
|
let lastTextStyle = firstRunStyle(paragraph);
|
|
7482
7792
|
for (let childIndex = 0; childIndex < paragraph.children.length; childIndex += 1) {
|
|
@@ -7542,7 +7852,8 @@ function buildParagraphPretextLayoutSource(paragraph, options) {
|
|
|
7542
7852
|
const tabWidthPx = resolveTabSpacerWidthPx(
|
|
7543
7853
|
tabStopPositionsPx,
|
|
7544
7854
|
approximateLineWidthPx,
|
|
7545
|
-
fallbackTabWidthPx
|
|
7855
|
+
fallbackTabWidthPx,
|
|
7856
|
+
usesCheckboxRowTabFallback
|
|
7546
7857
|
);
|
|
7547
7858
|
const spacerText = buildParagraphPretextTabSpacerText(
|
|
7548
7859
|
tabWidthPx,
|
|
@@ -8291,10 +8602,14 @@ function updateEstimatedLineWidthPxForText(currentLineWidthPx, text, style) {
|
|
|
8291
8602
|
const trailingSegment = segments[segments.length - 1] ?? "";
|
|
8292
8603
|
return estimateTextAdvanceWidthPx(trailingSegment, style);
|
|
8293
8604
|
}
|
|
8294
|
-
function resolveTabSpacerWidthPx(tabStopPositionsPx, currentLineWidthPx, fallbackWidthPx) {
|
|
8605
|
+
function resolveTabSpacerWidthPx(tabStopPositionsPx, currentLineWidthPx, fallbackWidthPx, fixedFallback = false) {
|
|
8295
8606
|
const safeFallback = Math.max(12, Math.round(fallbackWidthPx));
|
|
8296
8607
|
if (tabStopPositionsPx.length === 0) {
|
|
8297
|
-
|
|
8608
|
+
if (fixedFallback) {
|
|
8609
|
+
return safeFallback;
|
|
8610
|
+
}
|
|
8611
|
+
const nextStop2 = (Math.floor((currentLineWidthPx + 0.5) / safeFallback) + 1) * safeFallback;
|
|
8612
|
+
return Math.max(2, Math.round(nextStop2 - currentLineWidthPx));
|
|
8298
8613
|
}
|
|
8299
8614
|
const nextStop = tabStopPositionsPx.find(
|
|
8300
8615
|
(stop) => stop > currentLineWidthPx + 0.5
|
|
@@ -9047,7 +9362,23 @@ function singleLineAutoScaleForFontFamily(fontFamily) {
|
|
|
9047
9362
|
}
|
|
9048
9363
|
return WORD_SINGLE_LINE_AUTO_SCALE;
|
|
9049
9364
|
}
|
|
9365
|
+
function emptyParagraphLineScaleForFontFamily(fontFamily) {
|
|
9366
|
+
const normalized = normalizeFontFamilyToken(fontFamily) ?? fontFamily?.toLowerCase();
|
|
9367
|
+
if (!normalized) {
|
|
9368
|
+
return WORD_EMPTY_PARAGRAPH_LINE_SCALE;
|
|
9369
|
+
}
|
|
9370
|
+
if (normalized === "times roman" || normalized === "times new roman" || normalized === "cambria" || normalized === "garamond" || normalized === "georgia" || normalized === "book antiqua" || normalized === "palatino linotype") {
|
|
9371
|
+
return WORD_EMPTY_PARAGRAPH_LINE_SCALE_SERIF;
|
|
9372
|
+
}
|
|
9373
|
+
if (normalized === "arial") {
|
|
9374
|
+
return WORD_EMPTY_PARAGRAPH_LINE_SCALE_SANS;
|
|
9375
|
+
}
|
|
9376
|
+
return WORD_EMPTY_PARAGRAPH_LINE_SCALE;
|
|
9377
|
+
}
|
|
9050
9378
|
function resolveParagraphSingleLineAutoScale(paragraph, fontFamily) {
|
|
9379
|
+
if (paragraphHasOnlyWhitespaceText(paragraph)) {
|
|
9380
|
+
return emptyParagraphLineScaleForFontFamily(fontFamily);
|
|
9381
|
+
}
|
|
9051
9382
|
const baseScale = singleLineAutoScaleForFontFamily(fontFamily);
|
|
9052
9383
|
return paragraphHasCheckboxFormField(paragraph) ? Math.max(1.08, baseScale) : baseScale;
|
|
9053
9384
|
}
|
|
@@ -9762,36 +10093,6 @@ function resolveMaxPretextLineRangeEndIndexThatFits(layout, startLineIndex, maxE
|
|
|
9762
10093
|
}
|
|
9763
10094
|
return bestEnd;
|
|
9764
10095
|
}
|
|
9765
|
-
function estimateAbsoluteFloatingImageFootprintPx(paragraph, image) {
|
|
9766
|
-
if (!shouldRenderAbsoluteFloatingImage(image)) {
|
|
9767
|
-
return 0;
|
|
9768
|
-
}
|
|
9769
|
-
const floating = image.floating;
|
|
9770
|
-
if (!floating) {
|
|
9771
|
-
return 0;
|
|
9772
|
-
}
|
|
9773
|
-
const wrapType = (floating.wrapType ?? "none").trim().toLowerCase();
|
|
9774
|
-
if (wrapType !== "none") {
|
|
9775
|
-
return 0;
|
|
9776
|
-
}
|
|
9777
|
-
const behavesAsTextBearingFloatingTextBox = image.syntheticTextBox && !syntheticTextBoxContainsPictureLayer(image) && Boolean(floatingTextBoxVisibleTextFromImage(image));
|
|
9778
|
-
if (behavesAsTextBearingFloatingTextBox) {
|
|
9779
|
-
if (paragraphHasVisibleText2(paragraph) || paragraphHasFormField2(paragraph) || paragraphContainsSectionBreakProperties(paragraph)) {
|
|
9780
|
-
return 0;
|
|
9781
|
-
}
|
|
9782
|
-
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;
|
|
9783
|
-
const distTPx = Math.max(0, Math.round(floating.distTPx ?? 0));
|
|
9784
|
-
const distBPx = Math.max(0, Math.round(floating.distBPx ?? 0));
|
|
9785
|
-
return Math.max(
|
|
9786
|
-
MIN_PARAGRAPH_LINE_HEIGHT_PX,
|
|
9787
|
-
imageHeightPx + distTPx + distBPx
|
|
9788
|
-
);
|
|
9789
|
-
}
|
|
9790
|
-
if (floating.behindDocument) {
|
|
9791
|
-
return 0;
|
|
9792
|
-
}
|
|
9793
|
-
return 0;
|
|
9794
|
-
}
|
|
9795
10096
|
function resolveAutoLineSpacingMultiple(lineTwips, fallbackMultiple) {
|
|
9796
10097
|
if (!Number.isFinite(lineTwips)) {
|
|
9797
10098
|
return Math.max(MIN_AUTO_LINE_MULTIPLE, fallbackMultiple);
|
|
@@ -9889,8 +10190,15 @@ function estimateParagraphLineHeightPx(paragraph, docGridLinePitchPx, disableDoc
|
|
|
9889
10190
|
docGridMinimumLineHeightPx ?? 0
|
|
9890
10191
|
);
|
|
9891
10192
|
}
|
|
9892
|
-
const
|
|
9893
|
-
|
|
10193
|
+
const resolvedAutoMultiple = resolveAutoLineSpacingMultiple(
|
|
10194
|
+
lineTwips,
|
|
10195
|
+
defaultLineMultiple
|
|
10196
|
+
);
|
|
10197
|
+
const multiple = paragraphHasOnlyWhitespaceText(paragraph) ? Math.max(
|
|
10198
|
+
MIN_AUTO_LINE_MULTIPLE,
|
|
10199
|
+
Number((resolvedAutoMultiple * singleLineScale).toFixed(3))
|
|
10200
|
+
) : calibrateAutoLineSpacingMultiple(
|
|
10201
|
+
resolvedAutoMultiple,
|
|
9894
10202
|
baseFontFamily,
|
|
9895
10203
|
singleLineScale
|
|
9896
10204
|
);
|
|
@@ -9967,19 +10275,6 @@ function estimateParagraphHeightPx(paragraph, availableWidthPx, numberingDefinit
|
|
|
9967
10275
|
estimateWrappedFloatingImageFootprintPx(paragraph, child)
|
|
9968
10276
|
);
|
|
9969
10277
|
}, 0);
|
|
9970
|
-
const absoluteFloatingImageHeightPx = paragraph.children.reduce(
|
|
9971
|
-
(largest, child) => {
|
|
9972
|
-
if (child.type !== "image") {
|
|
9973
|
-
return largest;
|
|
9974
|
-
}
|
|
9975
|
-
return Math.max(
|
|
9976
|
-
largest,
|
|
9977
|
-
estimateAbsoluteFloatingImageFootprintPx(paragraph, child)
|
|
9978
|
-
);
|
|
9979
|
-
},
|
|
9980
|
-
0
|
|
9981
|
-
);
|
|
9982
|
-
const effectiveAbsoluteFloatingImageHeightPx = collapsibleAbsoluteFloatingAnchorOnlyParagraph || decorativeBehindTextAnchorOnlyParagraph ? 0 : absoluteFloatingImageHeightPx;
|
|
9983
10278
|
const emptyParagraphHeightPx = decorativeBehindTextAnchorOnlyParagraph ? 0 : paragraphIsEffectivelyEmpty(paragraph) ? lineHeightPx + EMPTY_PARAGRAPH_EXTRA_HEIGHT_PX : 0;
|
|
9984
10279
|
const topBorderInsetPx = paragraphBorderInsetPx(
|
|
9985
10280
|
paragraph.style?.borders?.top
|
|
@@ -9999,7 +10294,6 @@ function estimateParagraphHeightPx(paragraph, availableWidthPx, numberingDefinit
|
|
|
9999
10294
|
textFlowHeightPx,
|
|
10000
10295
|
inlineImageHeightPx,
|
|
10001
10296
|
wrappedFloatingImageHeightPx,
|
|
10002
|
-
effectiveAbsoluteFloatingImageHeightPx,
|
|
10003
10297
|
emptyParagraphHeightPx
|
|
10004
10298
|
);
|
|
10005
10299
|
if (excludeWrappedFloatingImageFootprint && paragraph.children.some((c) => c.type === "image")) {
|
|
@@ -11260,6 +11554,7 @@ function buildDocumentPageNodeSegments(model, pageContentHeightPx, pageContentWi
|
|
|
11260
11554
|
let previousParagraphAfterPx = 0;
|
|
11261
11555
|
let currentMetricsIndex = 0;
|
|
11262
11556
|
let currentSectionPageFlowOriginPx = 0;
|
|
11557
|
+
let committedKeepNextChainEndNodeIndex = -1;
|
|
11263
11558
|
let currentPageContentHeightPx = resolveMetricsPageContentHeightPx(
|
|
11264
11559
|
0,
|
|
11265
11560
|
metricsBySection[0]
|
|
@@ -11318,31 +11613,10 @@ function buildDocumentPageNodeSegments(model, pageContentHeightPx, pageContentWi
|
|
|
11318
11613
|
previousParagraphAfterPx = 0;
|
|
11319
11614
|
continue;
|
|
11320
11615
|
}
|
|
11321
|
-
if (node.type === "paragraph" && paragraphActsAsLeadingCoverLayoutPreambleSpacer(
|
|
11322
|
-
model,
|
|
11323
|
-
nodeIndex,
|
|
11324
|
-
node,
|
|
11325
|
-
nodeMetrics.pageContentWidthPx,
|
|
11326
|
-
nodeMetrics.pageContentHeightPx
|
|
11327
|
-
)) {
|
|
11328
|
-
previousParagraphAfterPx = 0;
|
|
11329
|
-
continue;
|
|
11330
|
-
}
|
|
11331
11616
|
if (node.type === "paragraph" && paragraphActsAsTrailingRenderedPageBreakSpacer(model, nodeIndex, node)) {
|
|
11332
11617
|
previousParagraphAfterPx = 0;
|
|
11333
11618
|
continue;
|
|
11334
11619
|
}
|
|
11335
|
-
if (node.type === "paragraph" && paragraphActsAsLeadingCoverLayoutOverlay(
|
|
11336
|
-
model,
|
|
11337
|
-
nodeIndex,
|
|
11338
|
-
node,
|
|
11339
|
-
nodeMetrics.pageContentWidthPx,
|
|
11340
|
-
nodeMetrics.pageContentHeightPx
|
|
11341
|
-
)) {
|
|
11342
|
-
currentPageSegments.push({ nodeIndex });
|
|
11343
|
-
previousParagraphAfterPx = 0;
|
|
11344
|
-
continue;
|
|
11345
|
-
}
|
|
11346
11620
|
if (node.type === "paragraph" && paragraphActsAsDecorativeBehindTextBackgroundOverlay(node)) {
|
|
11347
11621
|
currentPageSegments.push({ nodeIndex });
|
|
11348
11622
|
previousParagraphAfterPx = 0;
|
|
@@ -11352,22 +11626,6 @@ function buildDocumentPageNodeSegments(model, pageContentHeightPx, pageContentWi
|
|
|
11352
11626
|
continue;
|
|
11353
11627
|
}
|
|
11354
11628
|
if (node.type === "paragraph") {
|
|
11355
|
-
if (paragraphStartsNewPageAfterLeadingCoverLayout(
|
|
11356
|
-
model,
|
|
11357
|
-
nodeIndex,
|
|
11358
|
-
node,
|
|
11359
|
-
nodeMetrics.pageContentWidthPx,
|
|
11360
|
-
nodeMetrics.pageContentHeightPx
|
|
11361
|
-
) && currentPageSegments.length > 0) {
|
|
11362
|
-
startNextPage();
|
|
11363
|
-
pageConsumedHeightPx = 0;
|
|
11364
|
-
previousParagraphAfterPx = 0;
|
|
11365
|
-
currentSectionPageFlowOriginPx = 0;
|
|
11366
|
-
currentPageContentHeightPx = resolveMetricsPageContentHeightPx(
|
|
11367
|
-
currentPageIndex,
|
|
11368
|
-
nodeMetrics
|
|
11369
|
-
);
|
|
11370
|
-
}
|
|
11371
11629
|
if (paragraphHasPageBreakBefore2(node) && currentPageSegments.length > 0) {
|
|
11372
11630
|
startNextPage();
|
|
11373
11631
|
pageConsumedHeightPx = 0;
|
|
@@ -11451,18 +11709,12 @@ function buildDocumentPageNodeSegments(model, pageContentHeightPx, pageContentWi
|
|
|
11451
11709
|
1,
|
|
11452
11710
|
estimatedOrMeasuredHeightPx - directBeforeSpacingPx - directAfterSpacingPx + beforeSpacingPx + afterSpacingPx
|
|
11453
11711
|
);
|
|
11454
|
-
const
|
|
11455
|
-
model,
|
|
11456
|
-
nodeIndex,
|
|
11457
|
-
node,
|
|
11458
|
-
nodeMetrics.pageContentWidthPx,
|
|
11459
|
-
nodeMetrics.pageContentHeightPx
|
|
11460
|
-
);
|
|
11461
|
-
const paragraphTooTallForSinglePage = Math.max(rawNodeHeightPx, coverFootprintPx) > nodeMetrics.pageContentHeightPx + PAGE_OVERFLOW_TOLERANCE_PX;
|
|
11712
|
+
const paragraphTooTallForSinglePage = rawNodeHeightPx > nodeMetrics.pageContentHeightPx + PAGE_OVERFLOW_TOLERANCE_PX;
|
|
11462
11713
|
const keepLinesOverflowSplit = node.style?.keepLines === true && paragraphTooTallForSinglePage;
|
|
11463
11714
|
const keepNextOverflowSplit = node.style?.keepNext === true && paragraphTooTallForSinglePage;
|
|
11464
11715
|
const forceOverflowSplit = keepLinesOverflowSplit || keepNextOverflowSplit;
|
|
11465
|
-
|
|
11716
|
+
const nodeIsWithinCommittedKeepNextChain = nodeIndex <= committedKeepNextChainEndNodeIndex;
|
|
11717
|
+
if (forceOverflowSplit && !nodeIsWithinCommittedKeepNextChain && pageConsumedHeightPx > 0 && currentPageSegments.length > 0) {
|
|
11466
11718
|
startNextPage();
|
|
11467
11719
|
pageConsumedHeightPx = 0;
|
|
11468
11720
|
previousParagraphAfterPx = 0;
|
|
@@ -11475,7 +11727,7 @@ function buildDocumentPageNodeSegments(model, pageContentHeightPx, pageContentWi
|
|
|
11475
11727
|
const collapsedMarginPx = pageConsumedHeightPx > 0 ? Math.min(previousParagraphAfterPx, beforeSpacingPx) : 0;
|
|
11476
11728
|
const collapsedNodeHeightPx = Math.max(
|
|
11477
11729
|
1,
|
|
11478
|
-
|
|
11730
|
+
rawNodeHeightPx - collapsedMarginPx
|
|
11479
11731
|
);
|
|
11480
11732
|
const paragraphSupportsPretextSegmentRendering = Boolean(
|
|
11481
11733
|
paragraphPretextSourceForSegmentRendering
|
|
@@ -11501,7 +11753,7 @@ function buildDocumentPageNodeSegments(model, pageContentHeightPx, pageContentWi
|
|
|
11501
11753
|
}
|
|
11502
11754
|
const collapsedNodeHeightPxAdjusted = Math.max(
|
|
11503
11755
|
1,
|
|
11504
|
-
|
|
11756
|
+
rawNodeHeightPx - collapsedMarginPx
|
|
11505
11757
|
);
|
|
11506
11758
|
const paragraphPretextLineCount = paragraphContainsExplicitLineBreakText(node) || paragraphContainsTabCharacter(node) ? resolveParagraphPretextLayoutForSegmentRendering()?.lineCount : void 0;
|
|
11507
11759
|
const supportsImageParagraphLineSplit = paragraphHasImage2(node) && paragraphSupportsPretextSegmentRendering;
|
|
@@ -11725,7 +11977,8 @@ function buildDocumentPageNodeSegments(model, pageContentHeightPx, pageContentWi
|
|
|
11725
11977
|
continue;
|
|
11726
11978
|
}
|
|
11727
11979
|
let requiredHeightPx = collapsedNodeHeightPxAdjusted;
|
|
11728
|
-
|
|
11980
|
+
let keepNextChainEndNodeIndex = -1;
|
|
11981
|
+
if (node.style?.keepNext === true && !nodeIsWithinCommittedKeepNextChain && paragraphHasVisibleText2(node)) {
|
|
11729
11982
|
let chainCursor = nodeIndex;
|
|
11730
11983
|
let chainPreviousParagraphAfterPx = afterSpacingPx;
|
|
11731
11984
|
while (chainCursor < model.nodes.length - 1) {
|
|
@@ -11785,6 +12038,7 @@ function buildDocumentPageNodeSegments(model, pageContentHeightPx, pageContentWi
|
|
|
11785
12038
|
);
|
|
11786
12039
|
chainPreviousParagraphAfterPx = nextAfterSpacingPx;
|
|
11787
12040
|
}
|
|
12041
|
+
keepNextChainEndNodeIndex = chainCursor;
|
|
11788
12042
|
}
|
|
11789
12043
|
const remainingHeightPx = currentPageContentHeightPx - pageConsumedHeightPx;
|
|
11790
12044
|
const canKeepTrailingSectionTailOnCurrentPage = shouldKeepTrailingSectionTailOnCurrentPage(
|
|
@@ -11826,11 +12080,11 @@ function buildDocumentPageNodeSegments(model, pageContentHeightPx, pageContentWi
|
|
|
11826
12080
|
nodeMetrics
|
|
11827
12081
|
);
|
|
11828
12082
|
}
|
|
12083
|
+
if (pageConsumedHeightPx === 0 && keepNextChainEndNodeIndex > nodeIndex) {
|
|
12084
|
+
committedKeepNextChainEndNodeIndex = keepNextChainEndNodeIndex;
|
|
12085
|
+
}
|
|
11829
12086
|
currentPageSegments.push({ nodeIndex });
|
|
11830
|
-
const effectiveNodeHeightPx =
|
|
11831
|
-
pageConsumedHeightPx > 0 ? collapsedNodeHeightPx : rawNodeHeightPx,
|
|
11832
|
-
coverFootprintPx
|
|
11833
|
-
);
|
|
12087
|
+
const effectiveNodeHeightPx = pageConsumedHeightPx > 0 ? collapsedNodeHeightPx : rawNodeHeightPx;
|
|
11834
12088
|
pageConsumedHeightPx += effectiveNodeHeightPx;
|
|
11835
12089
|
previousParagraphAfterPx = afterSpacingPx;
|
|
11836
12090
|
continue;
|
|
@@ -12637,11 +12891,15 @@ function paragraphLineHeight(paragraph, docGridLinePitchPx, disableDocGridSnap =
|
|
|
12637
12891
|
disableDocGridSnap
|
|
12638
12892
|
)}px`;
|
|
12639
12893
|
}
|
|
12640
|
-
const
|
|
12641
|
-
|
|
12642
|
-
|
|
12643
|
-
|
|
12644
|
-
|
|
12894
|
+
const resolvedAutoMultiple = resolveAutoLineSpacingMultiple(
|
|
12895
|
+
lineTwips,
|
|
12896
|
+
DEFAULT_PARAGRAPH_LINE_MULTIPLE
|
|
12897
|
+
);
|
|
12898
|
+
const lineMultiple = paragraphHasOnlyWhitespaceText(paragraph) ? Math.max(
|
|
12899
|
+
MIN_AUTO_LINE_MULTIPLE,
|
|
12900
|
+
Number((resolvedAutoMultiple * singleLineScale).toFixed(3))
|
|
12901
|
+
) : calibrateAutoLineSpacingMultiple(
|
|
12902
|
+
resolvedAutoMultiple,
|
|
12645
12903
|
baseFontFamily,
|
|
12646
12904
|
singleLineScale
|
|
12647
12905
|
);
|
|
@@ -12985,8 +13243,7 @@ function paragraphBlockStyle(paragraph, numberingDefinitions, headingStyles, doc
|
|
|
12985
13243
|
const suppressIndentForFloatingAnchorOnlyParagraph = paragraphIsFloatingImageAnchorOnly(paragraph);
|
|
12986
13244
|
const suppressStackingContextForBehindTextAnchorOnlyParagraph = paragraphIsBehindTextAbsoluteFloatingImageAnchorOnly(paragraph);
|
|
12987
13245
|
const suppressFlowFootprintForBehindTextAnchorOnlyParagraph = paragraphActsAsDecorativeBehindTextBackgroundOverlay(paragraph);
|
|
12988
|
-
const
|
|
12989
|
-
const reservedMinHeightPx = suppressFlowFootprintForBehindTextAnchorOnlyParagraph ? void 0 : textBearingAbsoluteFloatingTextBoxFootprintPx > 0 ? textBearingAbsoluteFloatingTextBoxFootprintPx : paragraphIsEffectivelyEmpty(paragraph) ? estimateParagraphLineHeightPx(
|
|
13246
|
+
const reservedMinHeightPx = suppressFlowFootprintForBehindTextAnchorOnlyParagraph ? void 0 : paragraphIsEffectivelyEmpty(paragraph) ? estimateParagraphLineHeightPx(
|
|
12990
13247
|
paragraph,
|
|
12991
13248
|
docGridLinePitchPx,
|
|
12992
13249
|
disableDocGridSnap
|
|
@@ -14744,7 +15001,8 @@ function renderParagraphRuns(paragraph, keyPrefix, documentTheme = "light", numb
|
|
|
14744
15001
|
const resolveNextTabWidthPx = () => resolveTabSpacerWidthPx(
|
|
14745
15002
|
tabStopPositionsPx,
|
|
14746
15003
|
approximateLineWidthPx,
|
|
14747
|
-
fallbackTabWidthPx
|
|
15004
|
+
fallbackTabWidthPx,
|
|
15005
|
+
checkboxChoiceRow
|
|
14748
15006
|
);
|
|
14749
15007
|
const appendPlainTextWithSoftBreakControl = (target, keySeed, text, style, measureStyle) => {
|
|
14750
15008
|
const shouldControlSoftBreakStretch = paragraph.style?.align === "justify" && text.includes("\n");
|
|
@@ -22822,12 +23080,32 @@ function ensureDocxViewerPageSurfaceRegistry(editor) {
|
|
|
22822
23080
|
if (!registry) {
|
|
22823
23081
|
registry = {
|
|
22824
23082
|
pageElements: /* @__PURE__ */ new Map(),
|
|
23083
|
+
pageContentKeys: /* @__PURE__ */ new Map(),
|
|
22825
23084
|
listeners: /* @__PURE__ */ new Set()
|
|
22826
23085
|
};
|
|
22827
23086
|
docxViewerPageSurfaceRegistryByEditor.set(owner, registry);
|
|
22828
23087
|
}
|
|
22829
23088
|
return registry;
|
|
22830
23089
|
}
|
|
23090
|
+
function syncDocxViewerPageSurfaceContentKeys(editor, contentKeysByPage) {
|
|
23091
|
+
const registry = ensureDocxViewerPageSurfaceRegistry(editor);
|
|
23092
|
+
let changed = false;
|
|
23093
|
+
contentKeysByPage.forEach((contentKey, pageIndex) => {
|
|
23094
|
+
if (registry.pageContentKeys.get(pageIndex) !== contentKey) {
|
|
23095
|
+
registry.pageContentKeys.set(pageIndex, contentKey);
|
|
23096
|
+
changed = true;
|
|
23097
|
+
}
|
|
23098
|
+
});
|
|
23099
|
+
registry.pageContentKeys.forEach((_, pageIndex) => {
|
|
23100
|
+
if (pageIndex >= contentKeysByPage.length) {
|
|
23101
|
+
registry.pageContentKeys.delete(pageIndex);
|
|
23102
|
+
changed = true;
|
|
23103
|
+
}
|
|
23104
|
+
});
|
|
23105
|
+
if (changed) {
|
|
23106
|
+
notifyDocxViewerPageSurfaceSubscribers(registry);
|
|
23107
|
+
}
|
|
23108
|
+
}
|
|
22831
23109
|
function subscribeDocxViewerPageSurfaces(editor, listener) {
|
|
22832
23110
|
const registry = ensureDocxViewerPageSurfaceRegistry(editor);
|
|
22833
23111
|
registry.listeners.add(listener);
|
|
@@ -22891,62 +23169,8 @@ function resolveDocxViewerPageSurfaceSize(element, fallbackWidthPx, fallbackHeig
|
|
|
22891
23169
|
heightPx: Math.max(1, Math.round(fallbackHeightPx))
|
|
22892
23170
|
};
|
|
22893
23171
|
}
|
|
22894
|
-
|
|
22895
|
-
|
|
22896
|
-
throw new Error("DOCX thumbnails require a browser environment.");
|
|
22897
|
-
}
|
|
22898
|
-
const {
|
|
22899
|
-
pageElement,
|
|
22900
|
-
sourceWidthPx,
|
|
22901
|
-
sourceHeightPx,
|
|
22902
|
-
canvas,
|
|
22903
|
-
widthPx,
|
|
22904
|
-
heightPx,
|
|
22905
|
-
pixelWidthPx,
|
|
22906
|
-
pixelHeightPx
|
|
22907
|
-
} = params;
|
|
22908
|
-
const safeSourceWidthPx = Math.max(1, Math.round(sourceWidthPx));
|
|
22909
|
-
const safeSourceHeightPx = Math.max(1, Math.round(sourceHeightPx));
|
|
22910
|
-
const scaleX = widthPx / safeSourceWidthPx;
|
|
22911
|
-
const scaleY = heightPx / safeSourceHeightPx;
|
|
22912
|
-
const serializedPage = new XMLSerializer().serializeToString(
|
|
22913
|
-
pageElement.cloneNode(true)
|
|
22914
|
-
);
|
|
22915
|
-
const svgMarkup = `
|
|
22916
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="${widthPx}" height="${heightPx}" viewBox="0 0 ${widthPx} ${heightPx}">
|
|
22917
|
-
<foreignObject x="0" y="0" width="100%" height="100%">
|
|
22918
|
-
<div xmlns="http://www.w3.org/1999/xhtml" style="width:${widthPx}px;height:${heightPx}px;overflow:hidden;">
|
|
22919
|
-
<div style="width:${safeSourceWidthPx}px;height:${safeSourceHeightPx}px;transform-origin:top left;transform:scale(${scaleX}, ${scaleY});">
|
|
22920
|
-
${serializedPage}
|
|
22921
|
-
</div>
|
|
22922
|
-
</div>
|
|
22923
|
-
</foreignObject>
|
|
22924
|
-
</svg>
|
|
22925
|
-
`;
|
|
22926
|
-
const svgDataUrl = svgDataUri(svgMarkup);
|
|
22927
|
-
const image = await new Promise((resolve, reject) => {
|
|
22928
|
-
const nextImage = new Image();
|
|
22929
|
-
nextImage.decoding = "async";
|
|
22930
|
-
nextImage.onload = () => resolve(nextImage);
|
|
22931
|
-
nextImage.onerror = () => {
|
|
22932
|
-
reject(new Error("Failed to rasterize DOCX page thumbnail."));
|
|
22933
|
-
};
|
|
22934
|
-
nextImage.src = svgDataUrl;
|
|
22935
|
-
});
|
|
22936
|
-
canvas.width = Math.max(1, Math.round(pixelWidthPx));
|
|
22937
|
-
canvas.height = Math.max(1, Math.round(pixelHeightPx));
|
|
22938
|
-
canvas.style.width = `${Math.max(1, Math.round(widthPx))}px`;
|
|
22939
|
-
canvas.style.height = `${Math.max(1, Math.round(heightPx))}px`;
|
|
22940
|
-
const context = canvas.getContext("2d");
|
|
22941
|
-
if (!context) {
|
|
22942
|
-
throw new Error("2D canvas context is unavailable for DOCX thumbnails.");
|
|
22943
|
-
}
|
|
22944
|
-
context.setTransform(1, 0, 0, 1, 0, 0);
|
|
22945
|
-
context.clearRect(0, 0, canvas.width, canvas.height);
|
|
22946
|
-
context.imageSmoothingEnabled = true;
|
|
22947
|
-
context.imageSmoothingQuality = "high";
|
|
22948
|
-
context.drawImage(image, 0, 0, canvas.width, canvas.height);
|
|
22949
|
-
}
|
|
23172
|
+
var DOCX_THUMBNAIL_SURFACE_CACHE_MAX_ENTRIES = 32;
|
|
23173
|
+
var DOCX_THUMBNAIL_MIN_RASTER_INTERVAL_MS = 200;
|
|
22950
23174
|
function resolveDocxPageThumbnailResolution(options) {
|
|
22951
23175
|
const safeSourceWidthPx = Math.max(1, Math.round(options.sourceWidthPx));
|
|
22952
23176
|
const safeSourceHeightPx = Math.max(1, Math.round(options.sourceHeightPx));
|
|
@@ -23020,8 +23244,51 @@ function useDocxPageThumbnails(editor, options = {}) {
|
|
|
23020
23244
|
},
|
|
23021
23245
|
[]
|
|
23022
23246
|
);
|
|
23247
|
+
const thumbnailSurfaceCacheRef = React.useRef(void 0);
|
|
23248
|
+
const thumbnailRasterQueueRef = React.useRef(void 0);
|
|
23249
|
+
const lastPaintedThumbnailKeyByCanvasRef = React.useRef(
|
|
23250
|
+
/* @__PURE__ */ new WeakMap()
|
|
23251
|
+
);
|
|
23252
|
+
const ensureThumbnailSurfaceCache = React.useCallback(() => {
|
|
23253
|
+
if (!thumbnailSurfaceCacheRef.current) {
|
|
23254
|
+
thumbnailSurfaceCacheRef.current = new DocxThumbnailSurfaceCache(
|
|
23255
|
+
DOCX_THUMBNAIL_SURFACE_CACHE_MAX_ENTRIES
|
|
23256
|
+
);
|
|
23257
|
+
}
|
|
23258
|
+
return thumbnailSurfaceCacheRef.current;
|
|
23259
|
+
}, []);
|
|
23260
|
+
const ensureThumbnailRasterQueue = React.useCallback(() => {
|
|
23261
|
+
if (!thumbnailRasterQueueRef.current) {
|
|
23262
|
+
thumbnailRasterQueueRef.current = new SerialIdleTaskQueue({
|
|
23263
|
+
minTaskIntervalMs: DOCX_THUMBNAIL_MIN_RASTER_INTERVAL_MS
|
|
23264
|
+
});
|
|
23265
|
+
}
|
|
23266
|
+
return thumbnailRasterQueueRef.current;
|
|
23267
|
+
}, []);
|
|
23268
|
+
React.useEffect(() => {
|
|
23269
|
+
thumbnailSurfaceCacheRef.current?.clear();
|
|
23270
|
+
thumbnailRasterQueueRef.current?.clear();
|
|
23271
|
+
lastPaintedThumbnailKeyByCanvasRef.current = /* @__PURE__ */ new WeakMap();
|
|
23272
|
+
}, [editor.documentLoadNonce, pageSurfaceRegistryOwner]);
|
|
23273
|
+
const thumbnailResolutionOptionsKey = React.useMemo(() => {
|
|
23274
|
+
const bounds = options.resolution;
|
|
23275
|
+
const boundsKey = typeof bounds === "number" ? `n${bounds}` : bounds ? `b${bounds.maxWidth ?? ""}x${bounds.maxHeight ?? ""}` : "";
|
|
23276
|
+
return `${boundsKey}|${options.maxWidthPx ?? ""}|${options.maxHeightPx ?? ""}|${options.pixelRatio ?? ""}`;
|
|
23277
|
+
}, [
|
|
23278
|
+
options.maxHeightPx,
|
|
23279
|
+
options.maxWidthPx,
|
|
23280
|
+
options.pixelRatio,
|
|
23281
|
+
options.resolution
|
|
23282
|
+
]);
|
|
23283
|
+
const thumbnailSkipKeyForPage = React.useCallback(
|
|
23284
|
+
(pageIndex) => {
|
|
23285
|
+
const contentKey = pageSurfaceRegistry.pageContentKeys.get(pageIndex);
|
|
23286
|
+
return contentKey === void 0 ? void 0 : `${contentKey}|${editor.documentTheme}|${thumbnailResolutionOptionsKey}`;
|
|
23287
|
+
},
|
|
23288
|
+
[editor.documentTheme, pageSurfaceRegistry, thumbnailResolutionOptionsKey]
|
|
23289
|
+
);
|
|
23023
23290
|
const renderPageThumbnailToCanvas = React.useCallback(
|
|
23024
|
-
async (pageIndex, canvas) => {
|
|
23291
|
+
async (pageIndex, canvas, renderOptions) => {
|
|
23025
23292
|
if (options.disabled) {
|
|
23026
23293
|
return;
|
|
23027
23294
|
}
|
|
@@ -23029,63 +23296,101 @@ function useDocxPageThumbnails(editor, options = {}) {
|
|
|
23029
23296
|
if (!targetCanvas) {
|
|
23030
23297
|
return;
|
|
23031
23298
|
}
|
|
23032
|
-
const pageElement =
|
|
23299
|
+
const pageElement = pageSurfaceRegistry.pageElements.get(pageIndex);
|
|
23033
23300
|
if (!pageElement || !pageElement.isConnected) {
|
|
23034
23301
|
updatePageThumbnailState(pageIndex, "unavailable");
|
|
23035
23302
|
return;
|
|
23036
23303
|
}
|
|
23037
|
-
const
|
|
23038
|
-
|
|
23039
|
-
|
|
23040
|
-
|
|
23041
|
-
|
|
23042
|
-
|
|
23043
|
-
sourceWidthPx: sourceSize.widthPx,
|
|
23044
|
-
sourceHeightPx: sourceSize.heightPx,
|
|
23045
|
-
resolution: options.resolution,
|
|
23046
|
-
maxWidthPx: options.maxWidthPx,
|
|
23047
|
-
maxHeightPx: options.maxHeightPx,
|
|
23048
|
-
pixelRatio: options.pixelRatio
|
|
23049
|
-
});
|
|
23304
|
+
const force = renderOptions?.force === true;
|
|
23305
|
+
const lastPaintedKey = lastPaintedThumbnailKeyByCanvasRef.current.get(targetCanvas);
|
|
23306
|
+
if (!force && lastPaintedKey !== void 0 && lastPaintedKey === thumbnailSkipKeyForPage(pageIndex)) {
|
|
23307
|
+
updatePageThumbnailState(pageIndex, "ready");
|
|
23308
|
+
return;
|
|
23309
|
+
}
|
|
23050
23310
|
updatePageThumbnailState(pageIndex, "rendering");
|
|
23051
|
-
|
|
23052
|
-
|
|
23053
|
-
|
|
23311
|
+
await ensureThumbnailRasterQueue().enqueue(targetCanvas, async () => {
|
|
23312
|
+
const livePageElement = pageSurfaceRegistry.pageElements.get(pageIndex);
|
|
23313
|
+
if (!livePageElement || !livePageElement.isConnected) {
|
|
23314
|
+
updatePageThumbnailState(pageIndex, "unavailable");
|
|
23315
|
+
return;
|
|
23316
|
+
}
|
|
23317
|
+
const runSkipKey = thumbnailSkipKeyForPage(pageIndex);
|
|
23318
|
+
const sourceSize = resolveDocxViewerPageSurfaceSize(
|
|
23319
|
+
livePageElement,
|
|
23320
|
+
fallbackLayout.pageWidthPx,
|
|
23321
|
+
fallbackLayout.pageHeightPx
|
|
23322
|
+
);
|
|
23323
|
+
const resolution = resolveDocxPageThumbnailResolution({
|
|
23054
23324
|
sourceWidthPx: sourceSize.widthPx,
|
|
23055
23325
|
sourceHeightPx: sourceSize.heightPx,
|
|
23056
|
-
|
|
23057
|
-
|
|
23058
|
-
|
|
23059
|
-
|
|
23060
|
-
pixelHeightPx: resolution.pixelHeightPx
|
|
23326
|
+
resolution: options.resolution,
|
|
23327
|
+
maxWidthPx: options.maxWidthPx,
|
|
23328
|
+
maxHeightPx: options.maxHeightPx,
|
|
23329
|
+
pixelRatio: options.pixelRatio
|
|
23061
23330
|
});
|
|
23062
|
-
|
|
23063
|
-
|
|
23064
|
-
|
|
23065
|
-
|
|
23066
|
-
|
|
23067
|
-
|
|
23068
|
-
|
|
23069
|
-
|
|
23331
|
+
const surfaceKey = runSkipKey === void 0 ? void 0 : `${runSkipKey}|${sourceSize.widthPx}x${sourceSize.heightPx}|${resolution.pixelWidthPx}x${resolution.pixelHeightPx}`;
|
|
23332
|
+
const surfaceCache = ensureThumbnailSurfaceCache();
|
|
23333
|
+
try {
|
|
23334
|
+
let surface = !force && surfaceKey !== void 0 ? surfaceCache.get(surfaceKey) : void 0;
|
|
23335
|
+
if (!surface) {
|
|
23336
|
+
surface = await rasterizeDocxThumbnailSurface({
|
|
23337
|
+
pageElement: livePageElement,
|
|
23338
|
+
sourceWidthPx: sourceSize.widthPx,
|
|
23339
|
+
sourceHeightPx: sourceSize.heightPx,
|
|
23340
|
+
widthPx: resolution.widthPx,
|
|
23341
|
+
heightPx: resolution.heightPx,
|
|
23342
|
+
pixelWidthPx: resolution.pixelWidthPx,
|
|
23343
|
+
pixelHeightPx: resolution.pixelHeightPx
|
|
23344
|
+
});
|
|
23345
|
+
if (surfaceKey !== void 0) {
|
|
23346
|
+
surfaceCache.set(surfaceKey, surface);
|
|
23347
|
+
}
|
|
23348
|
+
}
|
|
23349
|
+
blitDocxThumbnailSurface(surface, targetCanvas, resolution);
|
|
23350
|
+
if (runSkipKey !== void 0) {
|
|
23351
|
+
lastPaintedThumbnailKeyByCanvasRef.current.set(
|
|
23352
|
+
targetCanvas,
|
|
23353
|
+
runSkipKey
|
|
23354
|
+
);
|
|
23355
|
+
}
|
|
23356
|
+
updatePageThumbnailState(pageIndex, "ready");
|
|
23357
|
+
} catch (error) {
|
|
23358
|
+
updatePageThumbnailState(
|
|
23359
|
+
pageIndex,
|
|
23360
|
+
"error",
|
|
23361
|
+
error instanceof Error ? error : new Error("Failed to render DOCX page thumbnail.")
|
|
23362
|
+
);
|
|
23363
|
+
}
|
|
23364
|
+
});
|
|
23070
23365
|
},
|
|
23071
23366
|
[
|
|
23367
|
+
ensureThumbnailRasterQueue,
|
|
23368
|
+
ensureThumbnailSurfaceCache,
|
|
23072
23369
|
fallbackLayout.pageHeightPx,
|
|
23073
23370
|
fallbackLayout.pageWidthPx,
|
|
23074
|
-
mountedPageElements,
|
|
23075
23371
|
options.disabled,
|
|
23076
23372
|
options.resolution,
|
|
23077
23373
|
options.maxHeightPx,
|
|
23078
23374
|
options.maxWidthPx,
|
|
23079
23375
|
options.pixelRatio,
|
|
23376
|
+
pageSurfaceRegistry,
|
|
23377
|
+
thumbnailSkipKeyForPage,
|
|
23080
23378
|
updatePageThumbnailState
|
|
23081
23379
|
]
|
|
23082
23380
|
);
|
|
23083
|
-
const
|
|
23084
|
-
|
|
23085
|
-
|
|
23086
|
-
|
|
23087
|
-
|
|
23088
|
-
|
|
23381
|
+
const requestAttachedThumbnailRenders = React.useCallback(
|
|
23382
|
+
async (renderOptions) => {
|
|
23383
|
+
const tasks = [...attachedCanvasByPageRef.current.keys()].map(
|
|
23384
|
+
(pageIndex) => renderPageThumbnailToCanvas(pageIndex, void 0, renderOptions)
|
|
23385
|
+
);
|
|
23386
|
+
await Promise.all(tasks);
|
|
23387
|
+
},
|
|
23388
|
+
[renderPageThumbnailToCanvas]
|
|
23389
|
+
);
|
|
23390
|
+
const rerenderAttachedThumbnails = React.useCallback(
|
|
23391
|
+
async () => requestAttachedThumbnailRenders({ force: true }),
|
|
23392
|
+
[requestAttachedThumbnailRenders]
|
|
23393
|
+
);
|
|
23089
23394
|
const renderPageThumbnailToCanvasRef = React.useRef(
|
|
23090
23395
|
renderPageThumbnailToCanvas
|
|
23091
23396
|
);
|
|
@@ -23097,7 +23402,7 @@ function useDocxPageThumbnails(editor, options = {}) {
|
|
|
23097
23402
|
renderToCanvasCallbacksRef.current.clear();
|
|
23098
23403
|
}, [pageSurfaceRegistryOwner]);
|
|
23099
23404
|
React.useEffect(() => {
|
|
23100
|
-
void
|
|
23405
|
+
void requestAttachedThumbnailRenders();
|
|
23101
23406
|
}, [
|
|
23102
23407
|
editor.documentLoadNonce,
|
|
23103
23408
|
editor.documentTheme,
|
|
@@ -23108,7 +23413,7 @@ function useDocxPageThumbnails(editor, options = {}) {
|
|
|
23108
23413
|
options.maxHeightPx,
|
|
23109
23414
|
options.maxWidthPx,
|
|
23110
23415
|
options.pixelRatio,
|
|
23111
|
-
|
|
23416
|
+
requestAttachedThumbnailRenders
|
|
23112
23417
|
]);
|
|
23113
23418
|
const thumbnails = React.useMemo(() => {
|
|
23114
23419
|
const totalPages = Math.max(1, editor.totalPages);
|
|
@@ -25498,6 +25803,42 @@ function DocxEditorViewer({
|
|
|
25498
25803
|
pageNodeSegmentsByPage,
|
|
25499
25804
|
primarySectionPropertiesXml
|
|
25500
25805
|
]);
|
|
25806
|
+
const pageThumbnailContentKeysByPage = React.useMemo(() => {
|
|
25807
|
+
const metadataSignature = docModelThumbnailMetadataSignature(
|
|
25808
|
+
editor.model.metadata
|
|
25809
|
+
);
|
|
25810
|
+
return pageNodeSegmentsByPage.map((pageSegments, pageIndex) => {
|
|
25811
|
+
const sectionInfo = pageSectionInfoByIndex[pageIndex];
|
|
25812
|
+
let nodeSignatures = "";
|
|
25813
|
+
for (const segment of pageSegments) {
|
|
25814
|
+
nodeSignatures += docNodeContentSignature(
|
|
25815
|
+
editor.model.nodes[segment.nodeIndex]
|
|
25816
|
+
);
|
|
25817
|
+
nodeSignatures += ",";
|
|
25818
|
+
}
|
|
25819
|
+
return [
|
|
25820
|
+
editor.documentLoadNonce,
|
|
25821
|
+
trackedChangesEnabled ? "tc1" : "tc0",
|
|
25822
|
+
metadataSignature,
|
|
25823
|
+
sectionInfo ? `${sectionInfo.sectionIndex}.${sectionInfo.pageNumber}` : "s?",
|
|
25824
|
+
pageNodeSegmentIdentityKeysByPage[pageIndex] ?? "",
|
|
25825
|
+
nodeSignatures
|
|
25826
|
+
].join("|");
|
|
25827
|
+
});
|
|
25828
|
+
}, [
|
|
25829
|
+
editor.documentLoadNonce,
|
|
25830
|
+
editor.model,
|
|
25831
|
+
pageNodeSegmentIdentityKeysByPage,
|
|
25832
|
+
pageNodeSegmentsByPage,
|
|
25833
|
+
pageSectionInfoByIndex,
|
|
25834
|
+
trackedChangesEnabled
|
|
25835
|
+
]);
|
|
25836
|
+
React.useEffect(() => {
|
|
25837
|
+
syncDocxViewerPageSurfaceContentKeys(
|
|
25838
|
+
editor,
|
|
25839
|
+
pageThumbnailContentKeysByPage
|
|
25840
|
+
);
|
|
25841
|
+
}, [pageSurfaceRegistryOwner, pageThumbnailContentKeysByPage]);
|
|
25501
25842
|
const resolveStyleRefFieldValueForPage = React.useMemo(() => {
|
|
25502
25843
|
const valueCache = /* @__PURE__ */ new Map();
|
|
25503
25844
|
const nodes = editor.model.nodes;
|
|
@@ -33214,6 +33555,7 @@ function DocxEditorViewer({
|
|
|
33214
33555
|
"span",
|
|
33215
33556
|
{
|
|
33216
33557
|
contentEditable: false,
|
|
33558
|
+
...{ [DOCX_THUMBNAIL_EXCLUDE_ATTRIBUTE]: "true" },
|
|
33217
33559
|
style: {
|
|
33218
33560
|
position: "absolute",
|
|
33219
33561
|
left: rect.left,
|
|
@@ -33236,6 +33578,7 @@ function DocxEditorViewer({
|
|
|
33236
33578
|
"span",
|
|
33237
33579
|
{
|
|
33238
33580
|
contentEditable: false,
|
|
33581
|
+
...{ [DOCX_THUMBNAIL_EXCLUDE_ATTRIBUTE]: "true" },
|
|
33239
33582
|
style: {
|
|
33240
33583
|
position: "absolute",
|
|
33241
33584
|
left: caretRect.left,
|
|
@@ -36439,13 +36782,6 @@ function DocxEditorViewer({
|
|
|
36439
36782
|
options?.pageFlowForeignExclusions ?? []
|
|
36440
36783
|
)
|
|
36441
36784
|
);
|
|
36442
|
-
const leadingCoverLayoutSpacer = paragraphActsAsLeadingCoverLayoutSpacer(
|
|
36443
|
-
editor.model,
|
|
36444
|
-
nodeIndex,
|
|
36445
|
-
node,
|
|
36446
|
-
paragraphContentWidthPx,
|
|
36447
|
-
resolvedPageLayout.pageHeightPx - resolvedPageLayout.marginsPx.top - resolvedPageLayout.marginsPx.bottom
|
|
36448
|
-
);
|
|
36449
36785
|
const beforeSpacingPx = effectiveParagraphBeforeSpacingPx(
|
|
36450
36786
|
editor.model,
|
|
36451
36787
|
nodeIndex,
|
|
@@ -36504,9 +36840,6 @@ function DocxEditorViewer({
|
|
|
36504
36840
|
lineHeight: 0,
|
|
36505
36841
|
overflow: "visible"
|
|
36506
36842
|
} : requiresPageAbsoluteContext ? { position: "static" } : requiresLocalAbsoluteContext ? { position: "relative" } : hasDualWrappedFloatingImage ? { position: "relative" } : void 0,
|
|
36507
|
-
...leadingCoverLayoutSpacer ? {
|
|
36508
|
-
minHeight: `${estimateParagraphLineHeightPx(node, nodeDocGridLinePitchPx) + EMPTY_PARAGRAPH_EXTRA_HEIGHT_PX + LEADING_COVER_SPACER_EXTRA_HEIGHT_PX}px`
|
|
36509
|
-
} : void 0,
|
|
36510
36843
|
// Carry the paragraph's run font on the editable host so text typed into
|
|
36511
36844
|
// it (which is a bare, not-yet-committed text node, not a styled run
|
|
36512
36845
|
// span) renders in the same font the committed run will use — i.e. the
|
|
@@ -37541,6 +37874,22 @@ ${currentText.slice(end)}`;
|
|
|
37541
37874
|
const rowSpanValue = cell.style?.rowSpan && cell.style.rowSpan > 1 ? cell.style.rowSpan : 1;
|
|
37542
37875
|
const colSpan = colSpanValue > 1 ? colSpanValue : void 0;
|
|
37543
37876
|
const rowSpan = rowSpanValue > 1 ? rowSpanValue : void 0;
|
|
37877
|
+
const exactRowSpanRows = node.rows.slice(
|
|
37878
|
+
rowIndex,
|
|
37879
|
+
rowIndex + rowSpanValue
|
|
37880
|
+
);
|
|
37881
|
+
const exactRowSpanClipHeightPx = exactRowSpanRows.length > 0 && exactRowSpanRows.every((spannedRow, rowOffset) => {
|
|
37882
|
+
const spannedHeightPx = rowHeightsPx[rowIndex + rowOffset];
|
|
37883
|
+
return spannedRow.style?.heightRule === "exact" && Number.isFinite(spannedHeightPx) && spannedHeightPx > 0;
|
|
37884
|
+
}) ? exactRowSpanRows.reduce(
|
|
37885
|
+
(sum, _spannedRow, rowOffset) => sum + Math.max(
|
|
37886
|
+
MIN_PARAGRAPH_LINE_HEIGHT_PX,
|
|
37887
|
+
Math.round(
|
|
37888
|
+
rowHeightsPx[rowIndex + rowOffset]
|
|
37889
|
+
)
|
|
37890
|
+
),
|
|
37891
|
+
0
|
|
37892
|
+
) : void 0;
|
|
37544
37893
|
const startColumnIndex = columnCursor;
|
|
37545
37894
|
const boundaryColumnIndex = startColumnIndex + colSpanValue - 1;
|
|
37546
37895
|
columnCursor += colSpanValue;
|
|
@@ -38659,12 +39008,11 @@ ${currentText.slice(end)}`;
|
|
|
38659
39008
|
style: {
|
|
38660
39009
|
display: "grid",
|
|
38661
39010
|
gap: 0,
|
|
38662
|
-
//
|
|
38663
|
-
//
|
|
38664
|
-
//
|
|
38665
|
-
|
|
38666
|
-
|
|
38667
|
-
maxHeight: resolvedRowHeightStyle.height,
|
|
39011
|
+
// Without the clip the row balloons to fit
|
|
39012
|
+
// content (height on a <tr>/<td> is only
|
|
39013
|
+
// ever a minimum).
|
|
39014
|
+
...exactRowSpanClipHeightPx !== void 0 && !isSlicedRow ? {
|
|
39015
|
+
maxHeight: `${exactRowSpanClipHeightPx}px`,
|
|
38668
39016
|
overflow: "hidden"
|
|
38669
39017
|
} : void 0
|
|
38670
39018
|
},
|
|
@@ -40451,11 +40799,27 @@ ${currentText.slice(end)}`;
|
|
|
40451
40799
|
currentGroup.segments.push(segment);
|
|
40452
40800
|
return;
|
|
40453
40801
|
}
|
|
40802
|
+
if (currentGroup && parseSectionStartType(
|
|
40803
|
+
documentSections[currentSectionIndex]?.sectionPropertiesXml
|
|
40804
|
+
) === "nextcolumn") {
|
|
40805
|
+
const previousColumns = sectionColumnsBySectionIndex[currentGroup.sectionIndex];
|
|
40806
|
+
const nextColumns = sectionColumnsBySectionIndex[currentSectionIndex];
|
|
40807
|
+
const sameGeometry = previousColumns && nextColumns && previousColumns.count === nextColumns.count && Math.abs(
|
|
40808
|
+
previousColumns.gapPx - nextColumns.gapPx
|
|
40809
|
+
) <= 2 && JSON.stringify(previousColumns.widthsPx ?? null) === JSON.stringify(nextColumns.widthsPx ?? null);
|
|
40810
|
+
if (sameGeometry) {
|
|
40811
|
+
currentGroup.segments.push(segment);
|
|
40812
|
+
return;
|
|
40813
|
+
}
|
|
40814
|
+
}
|
|
40454
40815
|
sectionGroups.push({
|
|
40455
40816
|
sectionIndex: currentSectionIndex,
|
|
40456
40817
|
segments: [segment]
|
|
40457
40818
|
});
|
|
40458
40819
|
});
|
|
40820
|
+
if (typeof window !== "undefined" && window.__docxDebugGroups) {
|
|
40821
|
+
console.log("[groups]", pageIndex, JSON.stringify(sectionGroups.map((g) => ({ s: g.sectionIndex, n: g.segments.map((x) => x.nodeIndex) }))));
|
|
40822
|
+
}
|
|
40459
40823
|
return sectionGroups.map((group, groupIndex) => {
|
|
40460
40824
|
const sectionColumns = sectionColumnsBySectionIndex[group.sectionIndex];
|
|
40461
40825
|
const isLastGroupOnPage = groupIndex === sectionGroups.length - 1;
|
|
@@ -40624,7 +40988,7 @@ ${currentText.slice(end)}`;
|
|
|
40624
40988
|
(editor.model.metadata.sections ?? []).filter(
|
|
40625
40989
|
(candidate) => parseSectionStartType(
|
|
40626
40990
|
candidate.sectionPropertiesXml
|
|
40627
|
-
) === "
|
|
40991
|
+
) === "nextcolumn"
|
|
40628
40992
|
).map(
|
|
40629
40993
|
(candidate) => Math.max(
|
|
40630
40994
|
0,
|
|
@@ -42542,6 +42906,7 @@ function collectDocxEstimatedOverflowBreakStartNodeIndexes(model, hardBreakStart
|
|
|
42542
42906
|
let pageConsumedHeightPx = 0;
|
|
42543
42907
|
let previousParagraphAfterPx = 0;
|
|
42544
42908
|
let currentMetricsIndex = 0;
|
|
42909
|
+
let committedKeepNextChainEndNodeIndex = -1;
|
|
42545
42910
|
const suppressSpacingBeforeAfterPageBreak = options?.suppressSpacingBeforeAfterPageBreak ?? false;
|
|
42546
42911
|
let currentPageContentHeightPx = metricsBySection[0]?.pageContentHeightPx ?? fallbackMetrics.pageContentHeightPx;
|
|
42547
42912
|
for (let nodeIndex = 0; nodeIndex < model.nodes.length; nodeIndex += 1) {
|
|
@@ -42579,7 +42944,8 @@ function collectDocxEstimatedOverflowBreakStartNodeIndexes(model, hardBreakStart
|
|
|
42579
42944
|
const collapsedMarginPx = node.type === "paragraph" && pageConsumedHeightPx > 0 ? Math.min(previousParagraphAfterPx, nodeBeforeSpacingPx) : 0;
|
|
42580
42945
|
const collapsedNodeHeightPx = Math.max(1, rawNodeHeightPx - collapsedMarginPx);
|
|
42581
42946
|
let requiredHeightPx = collapsedNodeHeightPx;
|
|
42582
|
-
|
|
42947
|
+
let keepNextChainEndNodeIndex = -1;
|
|
42948
|
+
if (node.type === "paragraph" && node.style?.keepNext === true && nodeIndex > committedKeepNextChainEndNodeIndex && callbacks.paragraphHasVisibleText(node)) {
|
|
42583
42949
|
let chainCursor = nodeIndex;
|
|
42584
42950
|
let chainPreviousParagraphAfterPx = paragraphAfterSpacingPx2(node);
|
|
42585
42951
|
while (chainCursor < model.nodes.length - 1) {
|
|
@@ -42637,6 +43003,7 @@ function collectDocxEstimatedOverflowBreakStartNodeIndexes(model, hardBreakStart
|
|
|
42637
43003
|
);
|
|
42638
43004
|
chainPreviousParagraphAfterPx = paragraphAfterSpacingPx2(nextChainNode);
|
|
42639
43005
|
}
|
|
43006
|
+
keepNextChainEndNodeIndex = chainCursor;
|
|
42640
43007
|
}
|
|
42641
43008
|
const remainingHeightPx = currentPageContentHeightPx - pageConsumedHeightPx;
|
|
42642
43009
|
if (pageConsumedHeightPx > 0 && requiredHeightPx > remainingHeightPx + pageOverflowTolerancePx) {
|
|
@@ -42645,6 +43012,9 @@ function collectDocxEstimatedOverflowBreakStartNodeIndexes(model, hardBreakStart
|
|
|
42645
43012
|
previousParagraphAfterPx = 0;
|
|
42646
43013
|
currentPageContentHeightPx = nodeMetrics.pageContentHeightPx;
|
|
42647
43014
|
}
|
|
43015
|
+
if (pageConsumedHeightPx === 0 && keepNextChainEndNodeIndex > nodeIndex) {
|
|
43016
|
+
committedKeepNextChainEndNodeIndex = keepNextChainEndNodeIndex;
|
|
43017
|
+
}
|
|
42648
43018
|
const effectiveNodeHeightPx = pageConsumedHeightPx > 0 ? collapsedNodeHeightPx : rawNodeHeightPx;
|
|
42649
43019
|
pageConsumedHeightPx += effectiveNodeHeightPx;
|
|
42650
43020
|
previousParagraphAfterPx = node.type === "paragraph" ? paragraphAfterSpacingPx2(node) : 0;
|
|
@@ -42696,6 +43066,7 @@ function buildDocumentPageNodeSegments2(model, pageContentHeightPx, pageContentW
|
|
|
42696
43066
|
let pageConsumedHeightPx = 0;
|
|
42697
43067
|
let previousParagraphAfterPx = 0;
|
|
42698
43068
|
let currentMetricsIndex = 0;
|
|
43069
|
+
let committedKeepNextChainEndNodeIndex = -1;
|
|
42699
43070
|
let currentPageContentHeightPx = resolvePageContentHeightPx(
|
|
42700
43071
|
0,
|
|
42701
43072
|
metricsBySection[0]?.pageContentHeightPx ?? fallbackMetrics.pageContentHeightPx
|
|
@@ -42759,7 +43130,8 @@ function buildDocumentPageNodeSegments2(model, pageContentHeightPx, pageContentW
|
|
|
42759
43130
|
const keepLinesOverflowSplit = node.style?.keepLines === true && paragraphTooTallForSinglePage;
|
|
42760
43131
|
const keepNextOverflowSplit = node.style?.keepNext === true && paragraphTooTallForSinglePage;
|
|
42761
43132
|
const forceOverflowSplit = keepLinesOverflowSplit || keepNextOverflowSplit;
|
|
42762
|
-
|
|
43133
|
+
const nodeIsWithinCommittedKeepNextChain = nodeIndex <= committedKeepNextChainEndNodeIndex;
|
|
43134
|
+
if (forceOverflowSplit && !nodeIsWithinCommittedKeepNextChain && pageConsumedHeightPx > 0 && currentPageSegments.length > 0) {
|
|
42763
43135
|
startNextPage();
|
|
42764
43136
|
pageConsumedHeightPx = 0;
|
|
42765
43137
|
previousParagraphAfterPx = 0;
|
|
@@ -42909,7 +43281,8 @@ function buildDocumentPageNodeSegments2(model, pageContentHeightPx, pageContentW
|
|
|
42909
43281
|
continue;
|
|
42910
43282
|
}
|
|
42911
43283
|
let requiredHeightPx = collapsedNodeHeightPx;
|
|
42912
|
-
|
|
43284
|
+
let keepNextChainEndNodeIndex = -1;
|
|
43285
|
+
if (node.style?.keepNext === true && !nodeIsWithinCommittedKeepNextChain && callbacks.paragraphHasVisibleText(node)) {
|
|
42913
43286
|
let chainCursor = nodeIndex;
|
|
42914
43287
|
let chainPreviousParagraphAfterPx = afterSpacingPx;
|
|
42915
43288
|
while (chainCursor < model.nodes.length - 1) {
|
|
@@ -42967,6 +43340,7 @@ function buildDocumentPageNodeSegments2(model, pageContentHeightPx, pageContentW
|
|
|
42967
43340
|
);
|
|
42968
43341
|
chainPreviousParagraphAfterPx = paragraphAfterSpacingPx2(nextChainNode);
|
|
42969
43342
|
}
|
|
43343
|
+
keepNextChainEndNodeIndex = chainCursor;
|
|
42970
43344
|
}
|
|
42971
43345
|
const remainingHeightPx = currentPageContentHeightPx - pageConsumedHeightPx;
|
|
42972
43346
|
if (pageConsumedHeightPx > 0 && requiredHeightPx > remainingHeightPx + pageOverflowTolerancePx) {
|
|
@@ -42978,6 +43352,9 @@ function buildDocumentPageNodeSegments2(model, pageContentHeightPx, pageContentW
|
|
|
42978
43352
|
nodeMetrics.pageContentHeightPx
|
|
42979
43353
|
);
|
|
42980
43354
|
}
|
|
43355
|
+
if (pageConsumedHeightPx === 0 && keepNextChainEndNodeIndex > nodeIndex) {
|
|
43356
|
+
committedKeepNextChainEndNodeIndex = keepNextChainEndNodeIndex;
|
|
43357
|
+
}
|
|
42981
43358
|
currentPageSegments.push({ nodeIndex });
|
|
42982
43359
|
const effectiveNodeHeightPx = pageConsumedHeightPx > 0 ? collapsedNodeHeightPx : rawNodeHeightPx;
|
|
42983
43360
|
pageConsumedHeightPx += effectiveNodeHeightPx;
|