@extend-ai/react-docx 0.7.0-alpha.2 → 0.7.0-alpha.4
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/{chunk-BGCGPO6Q.js → chunk-XLGR633U.js} +91 -5
- package/dist/chunk-XLGR633U.js.map +1 -0
- package/dist/docx_wasm_bg.wasm +0 -0
- package/dist/index.cjs +845 -387
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.js +756 -386
- package/dist/index.js.map +1 -1
- package/dist/{src-XA2NEWYM.js → src-IT7QNDVM.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-BGCGPO6Q.js.map +0 -1
- /package/dist/{src-XA2NEWYM.js.map → src-IT7QNDVM.js.map} +0 -0
package/dist/index.cjs
CHANGED
|
@@ -160,6 +160,15 @@ function __wbg_get_imports() {
|
|
|
160
160
|
getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
|
|
161
161
|
getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
|
|
162
162
|
},
|
|
163
|
+
__wbg___wbindgen_is_null_ced4761460071341: function(arg0) {
|
|
164
|
+
const ret = getObject(arg0) === null;
|
|
165
|
+
return ret;
|
|
166
|
+
},
|
|
167
|
+
__wbg___wbindgen_is_object_3a2c414391dbf751: function(arg0) {
|
|
168
|
+
const val = getObject(arg0);
|
|
169
|
+
const ret = typeof val === "object" && val !== null;
|
|
170
|
+
return ret;
|
|
171
|
+
},
|
|
163
172
|
__wbg___wbindgen_is_undefined_4410e3c20a99fa97: function(arg0) {
|
|
164
173
|
const ret = getObject(arg0) === void 0;
|
|
165
174
|
return ret;
|
|
@@ -175,12 +184,83 @@ function __wbg_get_imports() {
|
|
|
175
184
|
__wbg___wbindgen_throw_bbadd78c1bac3a77: function(arg0, arg1) {
|
|
176
185
|
throw new Error(getStringFromWasm0(arg0, arg1));
|
|
177
186
|
},
|
|
187
|
+
__wbg_create_00e11a7cefe80760: function(arg0) {
|
|
188
|
+
const ret = Object.create(getObject(arg0));
|
|
189
|
+
return addHeapObject(ret);
|
|
190
|
+
},
|
|
191
|
+
__wbg_get_52a8a619f7b88df6: function() {
|
|
192
|
+
return handleError(function(arg0, arg1) {
|
|
193
|
+
const ret = Reflect.get(getObject(arg0), getObject(arg1));
|
|
194
|
+
return addHeapObject(ret);
|
|
195
|
+
}, arguments);
|
|
196
|
+
},
|
|
197
|
+
__wbg_get_unchecked_46e778e3cec74b5e: function(arg0, arg1) {
|
|
198
|
+
const ret = getObject(arg0)[arg1 >>> 0];
|
|
199
|
+
return addHeapObject(ret);
|
|
200
|
+
},
|
|
201
|
+
__wbg_instanceof_ArrayBuffer_a581da923203f29f: function(arg0) {
|
|
202
|
+
let result;
|
|
203
|
+
try {
|
|
204
|
+
result = getObject(arg0) instanceof ArrayBuffer;
|
|
205
|
+
} catch (_) {
|
|
206
|
+
result = false;
|
|
207
|
+
}
|
|
208
|
+
const ret = result;
|
|
209
|
+
return ret;
|
|
210
|
+
},
|
|
211
|
+
__wbg_instanceof_Uint8Array_b6fe1ac89eba107e: function(arg0) {
|
|
212
|
+
let result;
|
|
213
|
+
try {
|
|
214
|
+
result = getObject(arg0) instanceof Uint8Array;
|
|
215
|
+
} catch (_) {
|
|
216
|
+
result = false;
|
|
217
|
+
}
|
|
218
|
+
const ret = result;
|
|
219
|
+
return ret;
|
|
220
|
+
},
|
|
221
|
+
__wbg_isArray_139f48e3c057ede8: function(arg0) {
|
|
222
|
+
const ret = Array.isArray(getObject(arg0));
|
|
223
|
+
return ret;
|
|
224
|
+
},
|
|
225
|
+
__wbg_keys_bd51ff67a9b04698: function(arg0) {
|
|
226
|
+
const ret = Object.keys(getObject(arg0));
|
|
227
|
+
return addHeapObject(ret);
|
|
228
|
+
},
|
|
229
|
+
__wbg_length_68a9d5278d084f4f: function(arg0) {
|
|
230
|
+
const ret = getObject(arg0).length;
|
|
231
|
+
return ret;
|
|
232
|
+
},
|
|
233
|
+
__wbg_length_fb04d16d7bdf6d4c: function(arg0) {
|
|
234
|
+
const ret = getObject(arg0).length;
|
|
235
|
+
return ret;
|
|
236
|
+
},
|
|
237
|
+
__wbg_new_20b778a4c5c691c3: function() {
|
|
238
|
+
const ret = new Object();
|
|
239
|
+
return addHeapObject(ret);
|
|
240
|
+
},
|
|
241
|
+
__wbg_new_b06772b280cc6e52: function(arg0) {
|
|
242
|
+
const ret = new Uint8Array(getObject(arg0));
|
|
243
|
+
return addHeapObject(ret);
|
|
244
|
+
},
|
|
245
|
+
__wbg_new_from_slice_bb2d1778c0b87eb1: function(arg0, arg1) {
|
|
246
|
+
const ret = new Uint8Array(getArrayU8FromWasm0(arg0, arg1));
|
|
247
|
+
return addHeapObject(ret);
|
|
248
|
+
},
|
|
178
249
|
__wbg_parse_246201845d0eb98c: function() {
|
|
179
250
|
return handleError(function(arg0, arg1) {
|
|
180
251
|
const ret = JSON.parse(getStringFromWasm0(arg0, arg1));
|
|
181
252
|
return addHeapObject(ret);
|
|
182
253
|
}, arguments);
|
|
183
254
|
},
|
|
255
|
+
__wbg_prototypesetcall_956c7493c68e29b4: function(arg0, arg1, arg2) {
|
|
256
|
+
Uint8Array.prototype.set.call(getArrayU8FromWasm0(arg0, arg1), getObject(arg2));
|
|
257
|
+
},
|
|
258
|
+
__wbg_set_a6ba3ac0e634b822: function() {
|
|
259
|
+
return handleError(function(arg0, arg1, arg2) {
|
|
260
|
+
const ret = Reflect.set(getObject(arg0), getObject(arg1), getObject(arg2));
|
|
261
|
+
return ret;
|
|
262
|
+
}, arguments);
|
|
263
|
+
},
|
|
184
264
|
__wbg_stringify_a42c95ea9a7591c9: function() {
|
|
185
265
|
return handleError(function(arg0) {
|
|
186
266
|
const ret = JSON.stringify(getObject(arg0));
|
|
@@ -474,9 +554,15 @@ async function defaultWasmSource() {
|
|
|
474
554
|
async function initWasm(source) {
|
|
475
555
|
if (!initPromise) {
|
|
476
556
|
const chosen = source ?? overrideSource;
|
|
477
|
-
initPromise = (chosen !== void 0 ? Promise.resolve(chosen) : defaultWasmSource()).then(
|
|
478
|
-
|
|
479
|
-
|
|
557
|
+
initPromise = (chosen !== void 0 ? Promise.resolve(chosen) : defaultWasmSource()).then((module_or_path) => __wbg_init({ module_or_path })).catch((error) => {
|
|
558
|
+
if (error instanceof WebAssembly.CompileError) {
|
|
559
|
+
throw new Error(
|
|
560
|
+
`react-docx: the bundled WebAssembly binary failed to compile. It requires WebAssembly SIMD support (Chrome 91+, Firefox 89+, Safari 16.4+, Node 16.4+). Original error: ${error.message}`,
|
|
561
|
+
{ cause: error }
|
|
562
|
+
);
|
|
563
|
+
}
|
|
564
|
+
throw error;
|
|
565
|
+
});
|
|
480
566
|
}
|
|
481
567
|
return initPromise;
|
|
482
568
|
}
|
|
@@ -515,7 +601,7 @@ function mapsToWasmPackage(input) {
|
|
|
515
601
|
}
|
|
516
602
|
const binaryAssets = {};
|
|
517
603
|
for (const [name, asset] of input.binaryAssets.entries()) {
|
|
518
|
-
binaryAssets[name] =
|
|
604
|
+
binaryAssets[name] = asset;
|
|
519
605
|
}
|
|
520
606
|
return { parts, binaryAssets };
|
|
521
607
|
}
|
|
@@ -2906,16 +2992,17 @@ function shouldAllowStoredPageCountReduction(options) {
|
|
|
2906
2992
|
if (targetPageCount >= estimatedPageCount) {
|
|
2907
2993
|
return true;
|
|
2908
2994
|
}
|
|
2995
|
+
const renderedBreakHintPageCount = Number.isFinite(
|
|
2996
|
+
options.renderedBreakHintPageCount
|
|
2997
|
+
) ? Math.max(1, Math.round(options.renderedBreakHintPageCount)) : void 0;
|
|
2998
|
+
const renderedBreakHintsSupportTarget = options.hasLastRenderedPageBreakHints === true && renderedBreakHintPageCount !== void 0 && targetPageCount >= renderedBreakHintPageCount;
|
|
2909
2999
|
if (options.hasMeasuredBodyFooterOverlap === true) {
|
|
2910
|
-
return
|
|
3000
|
+
return renderedBreakHintsSupportTarget;
|
|
2911
3001
|
}
|
|
2912
3002
|
if (options.hasLastRenderedPageBreakHints !== true) {
|
|
2913
3003
|
return true;
|
|
2914
3004
|
}
|
|
2915
|
-
|
|
2916
|
-
options.renderedBreakHintPageCount
|
|
2917
|
-
) ? Math.max(1, Math.round(options.renderedBreakHintPageCount)) : void 0;
|
|
2918
|
-
return renderedBreakHintPageCount !== void 0 && targetPageCount >= renderedBreakHintPageCount;
|
|
3005
|
+
return renderedBreakHintsSupportTarget;
|
|
2919
3006
|
}
|
|
2920
3007
|
function shouldLatchMeasuredBodyFooterOverlap(options) {
|
|
2921
3008
|
if (options.measuredBodyFooterOverlap !== true) {
|
|
@@ -4022,6 +4109,425 @@ function sliceLayoutToLineRange(layout, startLineIndex, endLineIndex) {
|
|
|
4022
4109
|
};
|
|
4023
4110
|
}
|
|
4024
4111
|
|
|
4112
|
+
// src/content-signature.ts
|
|
4113
|
+
init_cjs_shims();
|
|
4114
|
+
var FNV_OFFSET_BASIS = 2166136261;
|
|
4115
|
+
var FNV_PRIME = 16777619;
|
|
4116
|
+
var LONG_STRING_SAMPLE_LENGTH = 64;
|
|
4117
|
+
var LONG_STRING_THRESHOLD = 256;
|
|
4118
|
+
function fnv1aAppend(hash, text) {
|
|
4119
|
+
let next = hash;
|
|
4120
|
+
for (let index = 0; index < text.length; index += 1) {
|
|
4121
|
+
next ^= text.charCodeAt(index);
|
|
4122
|
+
next = Math.imul(next, FNV_PRIME);
|
|
4123
|
+
}
|
|
4124
|
+
return next >>> 0;
|
|
4125
|
+
}
|
|
4126
|
+
function fnv1aAppendString(hash, value) {
|
|
4127
|
+
if (value.length <= LONG_STRING_THRESHOLD) {
|
|
4128
|
+
return fnv1aAppend(fnv1aAppend(hash, `${value.length}:`), value);
|
|
4129
|
+
}
|
|
4130
|
+
const head = value.slice(0, LONG_STRING_SAMPLE_LENGTH);
|
|
4131
|
+
const middleIndex = Math.floor(value.length / 2);
|
|
4132
|
+
const middle = value.slice(
|
|
4133
|
+
middleIndex,
|
|
4134
|
+
middleIndex + LONG_STRING_SAMPLE_LENGTH
|
|
4135
|
+
);
|
|
4136
|
+
const tail = value.slice(value.length - LONG_STRING_SAMPLE_LENGTH);
|
|
4137
|
+
let next = fnv1aAppend(hash, `${value.length}:`);
|
|
4138
|
+
next = fnv1aAppend(next, head);
|
|
4139
|
+
next = fnv1aAppend(next, middle);
|
|
4140
|
+
return fnv1aAppend(next, tail);
|
|
4141
|
+
}
|
|
4142
|
+
function fnv1aAppendValue(hash, value) {
|
|
4143
|
+
if (value === null) {
|
|
4144
|
+
return fnv1aAppend(hash, "~n");
|
|
4145
|
+
}
|
|
4146
|
+
switch (typeof value) {
|
|
4147
|
+
case "undefined":
|
|
4148
|
+
return fnv1aAppend(hash, "~u");
|
|
4149
|
+
case "string":
|
|
4150
|
+
return fnv1aAppendString(fnv1aAppend(hash, "~s"), value);
|
|
4151
|
+
case "number":
|
|
4152
|
+
return fnv1aAppend(hash, `~#${value}`);
|
|
4153
|
+
case "boolean":
|
|
4154
|
+
return fnv1aAppend(hash, value ? "~t" : "~f");
|
|
4155
|
+
case "object":
|
|
4156
|
+
break;
|
|
4157
|
+
default:
|
|
4158
|
+
return fnv1aAppend(hash, "~x");
|
|
4159
|
+
}
|
|
4160
|
+
if (Array.isArray(value)) {
|
|
4161
|
+
let next2 = fnv1aAppend(hash, `~a${value.length}`);
|
|
4162
|
+
for (const entry of value) {
|
|
4163
|
+
next2 = fnv1aAppendValue(next2, entry);
|
|
4164
|
+
}
|
|
4165
|
+
return next2;
|
|
4166
|
+
}
|
|
4167
|
+
if (ArrayBuffer.isView(value) || value instanceof ArrayBuffer) {
|
|
4168
|
+
const byteLength = value instanceof ArrayBuffer ? value.byteLength : value.byteLength;
|
|
4169
|
+
return fnv1aAppend(hash, `~b${byteLength}`);
|
|
4170
|
+
}
|
|
4171
|
+
let next = fnv1aAppend(hash, "~o");
|
|
4172
|
+
for (const key of Object.keys(value)) {
|
|
4173
|
+
const entry = value[key];
|
|
4174
|
+
if (entry === void 0) {
|
|
4175
|
+
continue;
|
|
4176
|
+
}
|
|
4177
|
+
next = fnv1aAppend(next, key);
|
|
4178
|
+
next = fnv1aAppendValue(next, entry);
|
|
4179
|
+
}
|
|
4180
|
+
return next;
|
|
4181
|
+
}
|
|
4182
|
+
function contentHash(value) {
|
|
4183
|
+
return fnv1aAppendValue(FNV_OFFSET_BASIS, value).toString(36);
|
|
4184
|
+
}
|
|
4185
|
+
var nodeSignatureCache = /* @__PURE__ */ new WeakMap();
|
|
4186
|
+
function docNodeContentSignature(node) {
|
|
4187
|
+
if (typeof node !== "object" || node === null) {
|
|
4188
|
+
return contentHash(node);
|
|
4189
|
+
}
|
|
4190
|
+
const cached = nodeSignatureCache.get(node);
|
|
4191
|
+
if (cached !== void 0) {
|
|
4192
|
+
return cached;
|
|
4193
|
+
}
|
|
4194
|
+
const signature = contentHash(node);
|
|
4195
|
+
nodeSignatureCache.set(node, signature);
|
|
4196
|
+
return signature;
|
|
4197
|
+
}
|
|
4198
|
+
var metadataSignatureCache = /* @__PURE__ */ new WeakMap();
|
|
4199
|
+
function docModelThumbnailMetadataSignature(metadata) {
|
|
4200
|
+
const cached = metadataSignatureCache.get(metadata);
|
|
4201
|
+
if (cached !== void 0) {
|
|
4202
|
+
return cached;
|
|
4203
|
+
}
|
|
4204
|
+
const relevant = metadata;
|
|
4205
|
+
let hash = FNV_OFFSET_BASIS;
|
|
4206
|
+
hash = fnv1aAppendValue(hash, relevant.sections);
|
|
4207
|
+
hash = fnv1aAppendValue(hash, relevant.headerSections);
|
|
4208
|
+
hash = fnv1aAppendValue(hash, relevant.footerSections);
|
|
4209
|
+
hash = fnv1aAppendValue(hash, relevant.numberingDefinitions);
|
|
4210
|
+
hash = fnv1aAppendValue(hash, relevant.footnotes);
|
|
4211
|
+
hash = fnv1aAppendValue(hash, relevant.endnotes);
|
|
4212
|
+
hash = fnv1aAppendValue(hash, relevant.documentBackgroundColor);
|
|
4213
|
+
hash = fnv1aAppendValue(hash, relevant.compatibility);
|
|
4214
|
+
const signature = (hash >>> 0).toString(36);
|
|
4215
|
+
metadataSignatureCache.set(metadata, signature);
|
|
4216
|
+
return signature;
|
|
4217
|
+
}
|
|
4218
|
+
|
|
4219
|
+
// src/thumbnail-raster.ts
|
|
4220
|
+
init_cjs_shims();
|
|
4221
|
+
var DOCX_THUMBNAIL_EXCLUDE_ATTRIBUTE = "data-docx-thumbnail-exclude";
|
|
4222
|
+
var THUMBNAIL_EXCLUDED_CLONE_SELECTOR = [
|
|
4223
|
+
`[${DOCX_THUMBNAIL_EXCLUDE_ATTRIBUTE}="true"]`,
|
|
4224
|
+
"textarea",
|
|
4225
|
+
'[data-image-resize-handle="true"]',
|
|
4226
|
+
'[data-docx-table-move-handle="true"]'
|
|
4227
|
+
].join(",");
|
|
4228
|
+
var THUMBNAIL_IMAGE_DOWNSCALE_MIN_DATA_URI_LENGTH = 32768;
|
|
4229
|
+
var THUMBNAIL_IMAGE_DOWNSCALE_MAX_DIMENSION_PX = 512;
|
|
4230
|
+
var THUMBNAIL_IMAGE_JPEG_QUALITY = 0.78;
|
|
4231
|
+
function thumbnailSvgDataUri(svg) {
|
|
4232
|
+
return `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg)}`;
|
|
4233
|
+
}
|
|
4234
|
+
function thumbnailImageSourceQualifiesForDownscale(src) {
|
|
4235
|
+
return src.length >= THUMBNAIL_IMAGE_DOWNSCALE_MIN_DATA_URI_LENGTH && src.startsWith("data:image/") && !src.startsWith("data:image/svg");
|
|
4236
|
+
}
|
|
4237
|
+
async function loadThumbnailImage(src) {
|
|
4238
|
+
const image = new Image();
|
|
4239
|
+
image.decoding = "async";
|
|
4240
|
+
const loaded = new Promise((resolve, reject) => {
|
|
4241
|
+
image.onload = () => resolve(image);
|
|
4242
|
+
image.onerror = () => {
|
|
4243
|
+
reject(new Error("Failed to decode DOCX thumbnail image."));
|
|
4244
|
+
};
|
|
4245
|
+
});
|
|
4246
|
+
image.src = src;
|
|
4247
|
+
if (typeof image.decode === "function") {
|
|
4248
|
+
try {
|
|
4249
|
+
await image.decode();
|
|
4250
|
+
return image;
|
|
4251
|
+
} catch {
|
|
4252
|
+
}
|
|
4253
|
+
}
|
|
4254
|
+
return loaded;
|
|
4255
|
+
}
|
|
4256
|
+
var downscaledThumbnailImageCache = /* @__PURE__ */ new Map();
|
|
4257
|
+
async function downscaleThumbnailImageDataUri(src) {
|
|
4258
|
+
if (typeof document === "undefined") {
|
|
4259
|
+
return void 0;
|
|
4260
|
+
}
|
|
4261
|
+
const image = await loadThumbnailImage(src);
|
|
4262
|
+
const naturalWidth = image.naturalWidth || image.width;
|
|
4263
|
+
const naturalHeight = image.naturalHeight || image.height;
|
|
4264
|
+
if (!naturalWidth || !naturalHeight) {
|
|
4265
|
+
return void 0;
|
|
4266
|
+
}
|
|
4267
|
+
const scale = THUMBNAIL_IMAGE_DOWNSCALE_MAX_DIMENSION_PX / Math.max(naturalWidth, naturalHeight);
|
|
4268
|
+
if (scale >= 1) {
|
|
4269
|
+
return void 0;
|
|
4270
|
+
}
|
|
4271
|
+
const canvas = document.createElement("canvas");
|
|
4272
|
+
canvas.width = Math.max(1, Math.round(naturalWidth * scale));
|
|
4273
|
+
canvas.height = Math.max(1, Math.round(naturalHeight * scale));
|
|
4274
|
+
const context = canvas.getContext("2d");
|
|
4275
|
+
if (!context) {
|
|
4276
|
+
return void 0;
|
|
4277
|
+
}
|
|
4278
|
+
context.imageSmoothingEnabled = true;
|
|
4279
|
+
context.imageSmoothingQuality = "high";
|
|
4280
|
+
context.drawImage(image, 0, 0, canvas.width, canvas.height);
|
|
4281
|
+
const sourceIsJpeg = src.startsWith("data:image/jpeg") || src.startsWith("data:image/jpg");
|
|
4282
|
+
const downscaled = sourceIsJpeg ? canvas.toDataURL("image/jpeg", THUMBNAIL_IMAGE_JPEG_QUALITY) : canvas.toDataURL("image/png");
|
|
4283
|
+
return downscaled.length < src.length ? downscaled : void 0;
|
|
4284
|
+
}
|
|
4285
|
+
function getDownscaledThumbnailImageDataUri(src) {
|
|
4286
|
+
const cached = downscaledThumbnailImageCache.get(src);
|
|
4287
|
+
if (cached) {
|
|
4288
|
+
return cached;
|
|
4289
|
+
}
|
|
4290
|
+
const pending = downscaleThumbnailImageDataUri(src).catch(() => void 0);
|
|
4291
|
+
downscaledThumbnailImageCache.set(src, pending);
|
|
4292
|
+
return pending;
|
|
4293
|
+
}
|
|
4294
|
+
async function buildDocxThumbnailSvgMarkup(params) {
|
|
4295
|
+
const { pageElement, sourceWidthPx, sourceHeightPx, widthPx, heightPx } = params;
|
|
4296
|
+
const clone = pageElement.cloneNode(true);
|
|
4297
|
+
clone.querySelectorAll(THUMBNAIL_EXCLUDED_CLONE_SELECTOR).forEach((excluded) => {
|
|
4298
|
+
excluded.remove();
|
|
4299
|
+
});
|
|
4300
|
+
const cloneImages = Array.from(clone.querySelectorAll("img"));
|
|
4301
|
+
await Promise.all(
|
|
4302
|
+
cloneImages.map(async (cloneImage) => {
|
|
4303
|
+
const src = cloneImage.getAttribute("src");
|
|
4304
|
+
if (!src || !thumbnailImageSourceQualifiesForDownscale(src)) {
|
|
4305
|
+
return;
|
|
4306
|
+
}
|
|
4307
|
+
const downscaled = await getDownscaledThumbnailImageDataUri(src);
|
|
4308
|
+
if (downscaled) {
|
|
4309
|
+
cloneImage.setAttribute("src", downscaled);
|
|
4310
|
+
}
|
|
4311
|
+
})
|
|
4312
|
+
);
|
|
4313
|
+
const scaleX = widthPx / sourceWidthPx;
|
|
4314
|
+
const scaleY = heightPx / sourceHeightPx;
|
|
4315
|
+
const serializedPage = new XMLSerializer().serializeToString(clone);
|
|
4316
|
+
return `
|
|
4317
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="${widthPx}" height="${heightPx}" viewBox="0 0 ${widthPx} ${heightPx}">
|
|
4318
|
+
<foreignObject x="0" y="0" width="100%" height="100%">
|
|
4319
|
+
<div xmlns="http://www.w3.org/1999/xhtml" style="width:${widthPx}px;height:${heightPx}px;overflow:hidden;">
|
|
4320
|
+
<div style="width:${sourceWidthPx}px;height:${sourceHeightPx}px;transform-origin:top left;transform:scale(${scaleX}, ${scaleY});">
|
|
4321
|
+
${serializedPage}
|
|
4322
|
+
</div>
|
|
4323
|
+
</div>
|
|
4324
|
+
</foreignObject>
|
|
4325
|
+
</svg>
|
|
4326
|
+
`;
|
|
4327
|
+
}
|
|
4328
|
+
async function rasterizeDocxThumbnailSurface(params) {
|
|
4329
|
+
if (typeof window === "undefined" || typeof XMLSerializer === "undefined") {
|
|
4330
|
+
throw new Error("DOCX thumbnails require a browser environment.");
|
|
4331
|
+
}
|
|
4332
|
+
const safeSourceWidthPx = Math.max(1, Math.round(params.sourceWidthPx));
|
|
4333
|
+
const safeSourceHeightPx = Math.max(1, Math.round(params.sourceHeightPx));
|
|
4334
|
+
const svgMarkup = await buildDocxThumbnailSvgMarkup({
|
|
4335
|
+
pageElement: params.pageElement,
|
|
4336
|
+
sourceWidthPx: safeSourceWidthPx,
|
|
4337
|
+
sourceHeightPx: safeSourceHeightPx,
|
|
4338
|
+
widthPx: params.widthPx,
|
|
4339
|
+
heightPx: params.heightPx
|
|
4340
|
+
});
|
|
4341
|
+
const image = await loadThumbnailImage(thumbnailSvgDataUri(svgMarkup));
|
|
4342
|
+
const surface = document.createElement("canvas");
|
|
4343
|
+
surface.width = Math.max(1, Math.round(params.pixelWidthPx));
|
|
4344
|
+
surface.height = Math.max(1, Math.round(params.pixelHeightPx));
|
|
4345
|
+
const context = surface.getContext("2d");
|
|
4346
|
+
if (!context) {
|
|
4347
|
+
throw new Error("2D canvas context is unavailable for DOCX thumbnails.");
|
|
4348
|
+
}
|
|
4349
|
+
context.imageSmoothingEnabled = true;
|
|
4350
|
+
context.imageSmoothingQuality = "high";
|
|
4351
|
+
context.drawImage(image, 0, 0, surface.width, surface.height);
|
|
4352
|
+
return surface;
|
|
4353
|
+
}
|
|
4354
|
+
function blitDocxThumbnailSurface(surface, canvas, resolution) {
|
|
4355
|
+
canvas.width = Math.max(1, Math.round(resolution.pixelWidthPx));
|
|
4356
|
+
canvas.height = Math.max(1, Math.round(resolution.pixelHeightPx));
|
|
4357
|
+
canvas.style.width = `${Math.max(1, Math.round(resolution.widthPx))}px`;
|
|
4358
|
+
canvas.style.height = `${Math.max(1, Math.round(resolution.heightPx))}px`;
|
|
4359
|
+
const context = canvas.getContext("2d");
|
|
4360
|
+
if (!context) {
|
|
4361
|
+
throw new Error("2D canvas context is unavailable for DOCX thumbnails.");
|
|
4362
|
+
}
|
|
4363
|
+
context.setTransform(1, 0, 0, 1, 0, 0);
|
|
4364
|
+
context.clearRect(0, 0, canvas.width, canvas.height);
|
|
4365
|
+
context.drawImage(surface, 0, 0, canvas.width, canvas.height);
|
|
4366
|
+
}
|
|
4367
|
+
var DocxThumbnailSurfaceCache = class {
|
|
4368
|
+
constructor(maxEntries) {
|
|
4369
|
+
this.maxEntries = maxEntries;
|
|
4370
|
+
}
|
|
4371
|
+
entries = /* @__PURE__ */ new Map();
|
|
4372
|
+
get size() {
|
|
4373
|
+
return this.entries.size;
|
|
4374
|
+
}
|
|
4375
|
+
get(key) {
|
|
4376
|
+
const value = this.entries.get(key);
|
|
4377
|
+
if (value === void 0) {
|
|
4378
|
+
return void 0;
|
|
4379
|
+
}
|
|
4380
|
+
this.entries.delete(key);
|
|
4381
|
+
this.entries.set(key, value);
|
|
4382
|
+
return value;
|
|
4383
|
+
}
|
|
4384
|
+
set(key, value) {
|
|
4385
|
+
this.entries.delete(key);
|
|
4386
|
+
this.entries.set(key, value);
|
|
4387
|
+
while (this.entries.size > this.maxEntries) {
|
|
4388
|
+
const oldestKey = this.entries.keys().next().value;
|
|
4389
|
+
if (oldestKey === void 0) {
|
|
4390
|
+
break;
|
|
4391
|
+
}
|
|
4392
|
+
this.entries.delete(oldestKey);
|
|
4393
|
+
}
|
|
4394
|
+
}
|
|
4395
|
+
clear() {
|
|
4396
|
+
this.entries.clear();
|
|
4397
|
+
}
|
|
4398
|
+
};
|
|
4399
|
+
var IDLE_TASK_TIMEOUT_MS = 300;
|
|
4400
|
+
function defaultScheduleTask(callback) {
|
|
4401
|
+
const idleWindow = typeof window === "undefined" ? void 0 : window;
|
|
4402
|
+
if (!idleWindow || typeof idleWindow.requestIdleCallback !== "function") {
|
|
4403
|
+
setTimeout(callback, 16);
|
|
4404
|
+
return;
|
|
4405
|
+
}
|
|
4406
|
+
let invoked = false;
|
|
4407
|
+
const runOnce = () => {
|
|
4408
|
+
if (invoked) {
|
|
4409
|
+
return;
|
|
4410
|
+
}
|
|
4411
|
+
invoked = true;
|
|
4412
|
+
callback();
|
|
4413
|
+
};
|
|
4414
|
+
const idleHandle = idleWindow.requestIdleCallback(runOnce, {
|
|
4415
|
+
timeout: IDLE_TASK_TIMEOUT_MS
|
|
4416
|
+
});
|
|
4417
|
+
setTimeout(() => {
|
|
4418
|
+
if (invoked) {
|
|
4419
|
+
return;
|
|
4420
|
+
}
|
|
4421
|
+
if (typeof idleWindow.cancelIdleCallback === "function") {
|
|
4422
|
+
idleWindow.cancelIdleCallback(idleHandle);
|
|
4423
|
+
}
|
|
4424
|
+
runOnce();
|
|
4425
|
+
}, IDLE_TASK_TIMEOUT_MS + 50);
|
|
4426
|
+
}
|
|
4427
|
+
function defaultScheduleDelayed(callback, delayMs) {
|
|
4428
|
+
setTimeout(callback, delayMs);
|
|
4429
|
+
}
|
|
4430
|
+
var SerialIdleTaskQueue = class {
|
|
4431
|
+
pending = [];
|
|
4432
|
+
lastRunAtByKey = /* @__PURE__ */ new Map();
|
|
4433
|
+
scheduleTask;
|
|
4434
|
+
scheduleDelayed;
|
|
4435
|
+
minTaskIntervalMs;
|
|
4436
|
+
now;
|
|
4437
|
+
pumpScheduled = false;
|
|
4438
|
+
running = false;
|
|
4439
|
+
constructor(options) {
|
|
4440
|
+
this.scheduleTask = options?.scheduleTask ?? defaultScheduleTask;
|
|
4441
|
+
this.scheduleDelayed = options?.scheduleDelayed ?? defaultScheduleDelayed;
|
|
4442
|
+
this.minTaskIntervalMs = Math.max(0, options?.minTaskIntervalMs ?? 0);
|
|
4443
|
+
this.now = options?.now ?? (() => Date.now());
|
|
4444
|
+
}
|
|
4445
|
+
get pendingCount() {
|
|
4446
|
+
return this.pending.length;
|
|
4447
|
+
}
|
|
4448
|
+
enqueue(key, run) {
|
|
4449
|
+
return new Promise((resolve) => {
|
|
4450
|
+
const existing = this.pending.find((entry) => entry.key === key);
|
|
4451
|
+
if (existing) {
|
|
4452
|
+
existing.run = run;
|
|
4453
|
+
existing.resolvers.push(resolve);
|
|
4454
|
+
} else {
|
|
4455
|
+
this.pending.push({ key, run, resolvers: [resolve] });
|
|
4456
|
+
}
|
|
4457
|
+
this.schedulePump();
|
|
4458
|
+
});
|
|
4459
|
+
}
|
|
4460
|
+
/** Drops all queued tasks, resolving their waiters without running them. */
|
|
4461
|
+
clear() {
|
|
4462
|
+
const dropped = this.pending.splice(0, this.pending.length);
|
|
4463
|
+
this.lastRunAtByKey.clear();
|
|
4464
|
+
dropped.forEach((entry) => {
|
|
4465
|
+
entry.resolvers.forEach((resolveEntry) => {
|
|
4466
|
+
resolveEntry();
|
|
4467
|
+
});
|
|
4468
|
+
});
|
|
4469
|
+
}
|
|
4470
|
+
schedulePump() {
|
|
4471
|
+
if (this.pumpScheduled || this.running || this.pending.length === 0) {
|
|
4472
|
+
return;
|
|
4473
|
+
}
|
|
4474
|
+
this.pumpScheduled = true;
|
|
4475
|
+
this.scheduleTask(() => {
|
|
4476
|
+
this.pumpScheduled = false;
|
|
4477
|
+
void this.runNext();
|
|
4478
|
+
});
|
|
4479
|
+
}
|
|
4480
|
+
takeNextEligibleEntry() {
|
|
4481
|
+
if (this.pending.length === 0) {
|
|
4482
|
+
return void 0;
|
|
4483
|
+
}
|
|
4484
|
+
const now = this.now();
|
|
4485
|
+
let earliestWaitMs;
|
|
4486
|
+
for (let index = 0; index < this.pending.length; index += 1) {
|
|
4487
|
+
const candidate = this.pending[index];
|
|
4488
|
+
if (!candidate) {
|
|
4489
|
+
continue;
|
|
4490
|
+
}
|
|
4491
|
+
const lastRunAt = this.lastRunAtByKey.get(candidate.key);
|
|
4492
|
+
const waitMs = lastRunAt === void 0 ? 0 : lastRunAt + this.minTaskIntervalMs - now;
|
|
4493
|
+
if (waitMs <= 0) {
|
|
4494
|
+
this.pending.splice(index, 1);
|
|
4495
|
+
return { entry: candidate };
|
|
4496
|
+
}
|
|
4497
|
+
earliestWaitMs = earliestWaitMs === void 0 ? waitMs : Math.min(earliestWaitMs, waitMs);
|
|
4498
|
+
}
|
|
4499
|
+
return earliestWaitMs === void 0 ? void 0 : { retryDelayMs: earliestWaitMs };
|
|
4500
|
+
}
|
|
4501
|
+
async runNext() {
|
|
4502
|
+
if (this.running) {
|
|
4503
|
+
return;
|
|
4504
|
+
}
|
|
4505
|
+
const next = this.takeNextEligibleEntry();
|
|
4506
|
+
if (!next) {
|
|
4507
|
+
return;
|
|
4508
|
+
}
|
|
4509
|
+
if (!("entry" in next)) {
|
|
4510
|
+
this.scheduleDelayed(() => {
|
|
4511
|
+
this.schedulePump();
|
|
4512
|
+
}, next.retryDelayMs);
|
|
4513
|
+
return;
|
|
4514
|
+
}
|
|
4515
|
+
this.running = true;
|
|
4516
|
+
const { entry } = next;
|
|
4517
|
+
try {
|
|
4518
|
+
await entry.run();
|
|
4519
|
+
} catch {
|
|
4520
|
+
} finally {
|
|
4521
|
+
this.lastRunAtByKey.set(entry.key, this.now());
|
|
4522
|
+
this.running = false;
|
|
4523
|
+
entry.resolvers.forEach((resolveEntry) => {
|
|
4524
|
+
resolveEntry();
|
|
4525
|
+
});
|
|
4526
|
+
this.schedulePump();
|
|
4527
|
+
}
|
|
4528
|
+
}
|
|
4529
|
+
};
|
|
4530
|
+
|
|
4025
4531
|
// src/editor.tsx
|
|
4026
4532
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
4027
4533
|
var HIGHLIGHT_TO_CSS = {
|
|
@@ -4118,6 +4624,9 @@ var DEFAULT_PARAGRAPH_LINE_MULTIPLE = 1;
|
|
|
4118
4624
|
var WORD_SINGLE_LINE_AUTO_SCALE = 0.88;
|
|
4119
4625
|
var WORD_SINGLE_LINE_AUTO_SCALE_SANS = 0.9;
|
|
4120
4626
|
var WORD_SINGLE_LINE_AUTO_SCALE_SERIF = 1.08;
|
|
4627
|
+
var WORD_EMPTY_PARAGRAPH_LINE_SCALE = 1.21;
|
|
4628
|
+
var WORD_EMPTY_PARAGRAPH_LINE_SCALE_SERIF = 1.15;
|
|
4629
|
+
var WORD_EMPTY_PARAGRAPH_LINE_SCALE_SANS = 1.15;
|
|
4121
4630
|
var WORD_AUTO_LINE_SCALE_BLEND_END_MULTIPLE = 1.08;
|
|
4122
4631
|
var MIN_AUTO_LINE_MULTIPLE = 0.1;
|
|
4123
4632
|
var MIN_PARAGRAPH_LINE_HEIGHT_PX = 14;
|
|
@@ -4162,7 +4671,6 @@ var TEXT_MEASURE_CACHE_MAX_ENTRIES = 12e3;
|
|
|
4162
4671
|
var DEFAULT_TAB_STOP_PX = 48;
|
|
4163
4672
|
var TAB_LEADER_ZONE_GAP_PX = 20;
|
|
4164
4673
|
var EMPTY_PARAGRAPH_EXTRA_HEIGHT_PX = 0;
|
|
4165
|
-
var LEADING_COVER_SPACER_EXTRA_HEIGHT_PX = 2;
|
|
4166
4674
|
var PARAGRAPH_SEGMENT_TOP_BLEED_PX = 22;
|
|
4167
4675
|
var PARAGRAPH_SEGMENT_DESCENDER_BLEED_PX = 6;
|
|
4168
4676
|
var PARAGRAPH_SEGMENT_VISUAL_SAFETY_PX = 24;
|
|
@@ -6682,19 +7190,6 @@ function floatingTextBoxVisibleTextFromImage(image) {
|
|
|
6682
7190
|
const normalized = normalizeFloatingTextBoxComparisonText(text);
|
|
6683
7191
|
return normalized.length > 0 ? normalized : void 0;
|
|
6684
7192
|
}
|
|
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
7193
|
function paragraphVisibleTextIsOnlyAbsoluteFloatingTextBoxContent(paragraph) {
|
|
6699
7194
|
if (!paragraphHasVisibleText2(paragraph) || paragraphHasFormField2(paragraph)) {
|
|
6700
7195
|
return false;
|
|
@@ -6727,38 +7222,9 @@ function paragraphHasOnlyWhitespaceText(paragraph) {
|
|
|
6727
7222
|
return child.text.replace(/[\s\u00a0]+/g, "").length === 0;
|
|
6728
7223
|
});
|
|
6729
7224
|
}
|
|
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
7225
|
function paragraphContainsSectionBreakProperties(paragraph) {
|
|
6737
7226
|
return /<w:sectPr\b/i.test(paragraph.sourceXml ?? "");
|
|
6738
7227
|
}
|
|
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
|
-
function paragraphAbsoluteFloatingAnchorsDependOnParagraphFlow(paragraph) {
|
|
6754
|
-
return paragraph.children.some((child) => {
|
|
6755
|
-
if (child.type !== "image" || !shouldRenderAbsoluteFloatingImage(child) || child.syntheticTextBox !== true || !floatingTextBoxVisibleTextFromImage(child) || child.floating?.behindDocument !== true) {
|
|
6756
|
-
return false;
|
|
6757
|
-
}
|
|
6758
|
-
const verticalRelativeTo = child.floating?.verticalRelativeTo?.trim().toLowerCase();
|
|
6759
|
-
return verticalRelativeTo === void 0 || verticalRelativeTo === "" || verticalRelativeTo === "paragraph" || verticalRelativeTo === "line";
|
|
6760
|
-
});
|
|
6761
|
-
}
|
|
6762
7228
|
function likelyFullPageCoverImageRelativeToContentBox(image, pageContentWidthPx, pageContentHeightPx) {
|
|
6763
7229
|
if (!shouldRenderAbsoluteFloatingImage(image) || !image.floating) {
|
|
6764
7230
|
return false;
|
|
@@ -6841,21 +7307,6 @@ function paragraphParticipatesInLeadingCoverLayout(model, nodeIndex, pageContent
|
|
|
6841
7307
|
}
|
|
6842
7308
|
return sawLikelyCoverArtAnchor;
|
|
6843
7309
|
}
|
|
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
7310
|
function fullPageCoverImageRenderKey(nodeIndex, childIndex) {
|
|
6860
7311
|
return `${nodeIndex}:${childIndex}`;
|
|
6861
7312
|
}
|
|
@@ -6894,71 +7345,6 @@ function fullPageCoverAbsoluteFloatingImageStyle(image, layout, options) {
|
|
|
6894
7345
|
zIndex: floating?.behindDocument === true ? 0 : normalizedZIndex
|
|
6895
7346
|
};
|
|
6896
7347
|
}
|
|
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
7348
|
function paragraphLooksLikeCheckboxChoiceRow(paragraph) {
|
|
6963
7349
|
if (paragraph.children.some((child) => child.type === "image")) {
|
|
6964
7350
|
return false;
|
|
@@ -7476,7 +7862,8 @@ function buildParagraphPretextLayoutSource(paragraph, options) {
|
|
|
7476
7862
|
let combinedText = "";
|
|
7477
7863
|
const paragraphBaseFontPx = paragraphBaseFontSizePx(paragraph);
|
|
7478
7864
|
const tabStopPositionsPx = options?.expandTabsForLayout ? resolveParagraphTabStopsPx(paragraph) : [];
|
|
7479
|
-
const
|
|
7865
|
+
const usesCheckboxRowTabFallback = paragraphLooksLikeCheckboxChoiceRow(paragraph);
|
|
7866
|
+
const fallbackTabWidthPx = usesCheckboxRowTabFallback ? checkboxChoiceRowTabWidthPx(paragraph) : DEFAULT_TAB_STOP_PX;
|
|
7480
7867
|
let approximateLineWidthPx = 0;
|
|
7481
7868
|
let lastTextStyle = firstRunStyle(paragraph);
|
|
7482
7869
|
for (let childIndex = 0; childIndex < paragraph.children.length; childIndex += 1) {
|
|
@@ -7542,7 +7929,8 @@ function buildParagraphPretextLayoutSource(paragraph, options) {
|
|
|
7542
7929
|
const tabWidthPx = resolveTabSpacerWidthPx(
|
|
7543
7930
|
tabStopPositionsPx,
|
|
7544
7931
|
approximateLineWidthPx,
|
|
7545
|
-
fallbackTabWidthPx
|
|
7932
|
+
fallbackTabWidthPx,
|
|
7933
|
+
usesCheckboxRowTabFallback
|
|
7546
7934
|
);
|
|
7547
7935
|
const spacerText = buildParagraphPretextTabSpacerText(
|
|
7548
7936
|
tabWidthPx,
|
|
@@ -8291,10 +8679,14 @@ function updateEstimatedLineWidthPxForText(currentLineWidthPx, text, style) {
|
|
|
8291
8679
|
const trailingSegment = segments[segments.length - 1] ?? "";
|
|
8292
8680
|
return estimateTextAdvanceWidthPx(trailingSegment, style);
|
|
8293
8681
|
}
|
|
8294
|
-
function resolveTabSpacerWidthPx(tabStopPositionsPx, currentLineWidthPx, fallbackWidthPx) {
|
|
8682
|
+
function resolveTabSpacerWidthPx(tabStopPositionsPx, currentLineWidthPx, fallbackWidthPx, fixedFallback = false) {
|
|
8295
8683
|
const safeFallback = Math.max(12, Math.round(fallbackWidthPx));
|
|
8296
8684
|
if (tabStopPositionsPx.length === 0) {
|
|
8297
|
-
|
|
8685
|
+
if (fixedFallback) {
|
|
8686
|
+
return safeFallback;
|
|
8687
|
+
}
|
|
8688
|
+
const nextStop2 = (Math.floor((currentLineWidthPx + 0.5) / safeFallback) + 1) * safeFallback;
|
|
8689
|
+
return Math.max(2, Math.round(nextStop2 - currentLineWidthPx));
|
|
8298
8690
|
}
|
|
8299
8691
|
const nextStop = tabStopPositionsPx.find(
|
|
8300
8692
|
(stop) => stop > currentLineWidthPx + 0.5
|
|
@@ -9047,7 +9439,26 @@ function singleLineAutoScaleForFontFamily(fontFamily) {
|
|
|
9047
9439
|
}
|
|
9048
9440
|
return WORD_SINGLE_LINE_AUTO_SCALE;
|
|
9049
9441
|
}
|
|
9442
|
+
function emptyParagraphLineScaleForFontFamily(fontFamily) {
|
|
9443
|
+
const normalized = normalizeFontFamilyToken(fontFamily) ?? fontFamily?.toLowerCase();
|
|
9444
|
+
if (!normalized) {
|
|
9445
|
+
return WORD_EMPTY_PARAGRAPH_LINE_SCALE;
|
|
9446
|
+
}
|
|
9447
|
+
if (normalized === "times roman" || normalized === "times new roman" || normalized === "cambria" || normalized === "garamond" || normalized === "georgia" || normalized === "book antiqua" || normalized === "palatino linotype") {
|
|
9448
|
+
return WORD_EMPTY_PARAGRAPH_LINE_SCALE_SERIF;
|
|
9449
|
+
}
|
|
9450
|
+
if (normalized === "arial") {
|
|
9451
|
+
return WORD_EMPTY_PARAGRAPH_LINE_SCALE_SANS;
|
|
9452
|
+
}
|
|
9453
|
+
return WORD_EMPTY_PARAGRAPH_LINE_SCALE;
|
|
9454
|
+
}
|
|
9455
|
+
function paragraphRendersTextFreeLine(paragraph) {
|
|
9456
|
+
return paragraphHasOnlyWhitespaceText(paragraph) || paragraphIsFloatingImageAnchorOnly(paragraph);
|
|
9457
|
+
}
|
|
9050
9458
|
function resolveParagraphSingleLineAutoScale(paragraph, fontFamily) {
|
|
9459
|
+
if (paragraphRendersTextFreeLine(paragraph)) {
|
|
9460
|
+
return emptyParagraphLineScaleForFontFamily(fontFamily);
|
|
9461
|
+
}
|
|
9051
9462
|
const baseScale = singleLineAutoScaleForFontFamily(fontFamily);
|
|
9052
9463
|
return paragraphHasCheckboxFormField(paragraph) ? Math.max(1.08, baseScale) : baseScale;
|
|
9053
9464
|
}
|
|
@@ -9762,36 +10173,6 @@ function resolveMaxPretextLineRangeEndIndexThatFits(layout, startLineIndex, maxE
|
|
|
9762
10173
|
}
|
|
9763
10174
|
return bestEnd;
|
|
9764
10175
|
}
|
|
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
10176
|
function resolveAutoLineSpacingMultiple(lineTwips, fallbackMultiple) {
|
|
9796
10177
|
if (!Number.isFinite(lineTwips)) {
|
|
9797
10178
|
return Math.max(MIN_AUTO_LINE_MULTIPLE, fallbackMultiple);
|
|
@@ -9889,8 +10270,15 @@ function estimateParagraphLineHeightPx(paragraph, docGridLinePitchPx, disableDoc
|
|
|
9889
10270
|
docGridMinimumLineHeightPx ?? 0
|
|
9890
10271
|
);
|
|
9891
10272
|
}
|
|
9892
|
-
const
|
|
9893
|
-
|
|
10273
|
+
const resolvedAutoMultiple = resolveAutoLineSpacingMultiple(
|
|
10274
|
+
lineTwips,
|
|
10275
|
+
defaultLineMultiple
|
|
10276
|
+
);
|
|
10277
|
+
const multiple = paragraphRendersTextFreeLine(paragraph) ? Math.max(
|
|
10278
|
+
MIN_AUTO_LINE_MULTIPLE,
|
|
10279
|
+
Number((resolvedAutoMultiple * singleLineScale).toFixed(3))
|
|
10280
|
+
) : calibrateAutoLineSpacingMultiple(
|
|
10281
|
+
resolvedAutoMultiple,
|
|
9894
10282
|
baseFontFamily,
|
|
9895
10283
|
singleLineScale
|
|
9896
10284
|
);
|
|
@@ -9945,10 +10333,7 @@ function estimateParagraphHeightPx(paragraph, availableWidthPx, numberingDefinit
|
|
|
9945
10333
|
numberingLabel
|
|
9946
10334
|
);
|
|
9947
10335
|
const absoluteFloatingAnchorOnlyParagraph = paragraphIsAbsoluteFloatingImageAnchorOnly(paragraph);
|
|
9948
|
-
const
|
|
9949
|
-
const collapsibleAbsoluteFloatingAnchorOnlyParagraph = absoluteFloatingAnchorOnlyParagraph && (!paragraphAbsoluteFloatingAnchorsDependOnParagraphFlow(paragraph) || sectionBreakAnchorCarryoverParagraph);
|
|
9950
|
-
const paragraphFlowAnchoredAbsoluteFloatingAnchorOnlyParagraph = absoluteFloatingAnchorOnlyParagraph && !collapsibleAbsoluteFloatingAnchorOnlyParagraph;
|
|
9951
|
-
const decorativeBehindTextAnchorOnlyParagraph = paragraphActsAsDecorativeBehindTextBackgroundOverlay(paragraph);
|
|
10336
|
+
const collapsibleAbsoluteFloatingAnchorOnlyParagraph = absoluteFloatingAnchorOnlyParagraph && paragraphIsSectionBreakAnchorCarryover(paragraph);
|
|
9952
10337
|
const inlineImageHeightPx = paragraph.children.reduce((largest, child) => {
|
|
9953
10338
|
if (child.type !== "image") {
|
|
9954
10339
|
return largest;
|
|
@@ -9967,27 +10352,14 @@ function estimateParagraphHeightPx(paragraph, availableWidthPx, numberingDefinit
|
|
|
9967
10352
|
estimateWrappedFloatingImageFootprintPx(paragraph, child)
|
|
9968
10353
|
);
|
|
9969
10354
|
}, 0);
|
|
9970
|
-
const
|
|
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
|
-
const emptyParagraphHeightPx = decorativeBehindTextAnchorOnlyParagraph ? 0 : paragraphIsEffectivelyEmpty(paragraph) ? lineHeightPx + EMPTY_PARAGRAPH_EXTRA_HEIGHT_PX : 0;
|
|
10355
|
+
const emptyParagraphHeightPx = paragraphIsEffectivelyEmpty(paragraph) ? lineHeightPx + EMPTY_PARAGRAPH_EXTRA_HEIGHT_PX : 0;
|
|
9984
10356
|
const topBorderInsetPx = paragraphBorderInsetPx(
|
|
9985
10357
|
paragraph.style?.borders?.top
|
|
9986
10358
|
);
|
|
9987
10359
|
const bottomBorderInsetPx = paragraphBorderInsetPx(
|
|
9988
10360
|
paragraph.style?.borders?.bottom
|
|
9989
10361
|
);
|
|
9990
|
-
const textFlowHeightPx = collapsibleAbsoluteFloatingAnchorOnlyParagraph ? 0 :
|
|
10362
|
+
const textFlowHeightPx = collapsibleAbsoluteFloatingAnchorOnlyParagraph ? 0 : (
|
|
9991
10363
|
// When excluding the wrapped-float footprint, the dual-wrapped block
|
|
9992
10364
|
// height spans the image; but the rendered paragraph only occupies its
|
|
9993
10365
|
// text lines while the float overhangs. Use the text-line height so the
|
|
@@ -9995,11 +10367,10 @@ function estimateParagraphHeightPx(paragraph, availableWidthPx, numberingDefinit
|
|
|
9995
10367
|
dualWrappedLayout && !excludeWrappedFloatingImageFootprint ? wrappedPretextParagraphBlockHeightPx(dualWrappedLayout.layout) : lineHeightPx * lineCount
|
|
9996
10368
|
);
|
|
9997
10369
|
const contentHeightPx = Math.max(
|
|
9998
|
-
collapsibleAbsoluteFloatingAnchorOnlyParagraph
|
|
10370
|
+
collapsibleAbsoluteFloatingAnchorOnlyParagraph ? 0 : lineHeightPx,
|
|
9999
10371
|
textFlowHeightPx,
|
|
10000
10372
|
inlineImageHeightPx,
|
|
10001
10373
|
wrappedFloatingImageHeightPx,
|
|
10002
|
-
effectiveAbsoluteFloatingImageHeightPx,
|
|
10003
10374
|
emptyParagraphHeightPx
|
|
10004
10375
|
);
|
|
10005
10376
|
if (excludeWrappedFloatingImageFootprint && paragraph.children.some((c) => c.type === "image")) {
|
|
@@ -11260,6 +11631,7 @@ function buildDocumentPageNodeSegments(model, pageContentHeightPx, pageContentWi
|
|
|
11260
11631
|
let previousParagraphAfterPx = 0;
|
|
11261
11632
|
let currentMetricsIndex = 0;
|
|
11262
11633
|
let currentSectionPageFlowOriginPx = 0;
|
|
11634
|
+
let committedKeepNextChainEndNodeIndex = -1;
|
|
11263
11635
|
let currentPageContentHeightPx = resolveMetricsPageContentHeightPx(
|
|
11264
11636
|
0,
|
|
11265
11637
|
metricsBySection[0]
|
|
@@ -11318,56 +11690,14 @@ function buildDocumentPageNodeSegments(model, pageContentHeightPx, pageContentWi
|
|
|
11318
11690
|
previousParagraphAfterPx = 0;
|
|
11319
11691
|
continue;
|
|
11320
11692
|
}
|
|
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
11693
|
if (node.type === "paragraph" && paragraphActsAsTrailingRenderedPageBreakSpacer(model, nodeIndex, node)) {
|
|
11332
11694
|
previousParagraphAfterPx = 0;
|
|
11333
11695
|
continue;
|
|
11334
11696
|
}
|
|
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
|
-
if (node.type === "paragraph" && paragraphActsAsDecorativeBehindTextBackgroundOverlay(node)) {
|
|
11347
|
-
currentPageSegments.push({ nodeIndex });
|
|
11348
|
-
previousParagraphAfterPx = 0;
|
|
11349
|
-
continue;
|
|
11350
|
-
}
|
|
11351
11697
|
if (node.type === "paragraph" && paragraphCollapsesIntoPreviousParagraph(node, model.nodes[nodeIndex - 1])) {
|
|
11352
11698
|
continue;
|
|
11353
11699
|
}
|
|
11354
11700
|
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
11701
|
if (paragraphHasPageBreakBefore2(node) && currentPageSegments.length > 0) {
|
|
11372
11702
|
startNextPage();
|
|
11373
11703
|
pageConsumedHeightPx = 0;
|
|
@@ -11451,18 +11781,12 @@ function buildDocumentPageNodeSegments(model, pageContentHeightPx, pageContentWi
|
|
|
11451
11781
|
1,
|
|
11452
11782
|
estimatedOrMeasuredHeightPx - directBeforeSpacingPx - directAfterSpacingPx + beforeSpacingPx + afterSpacingPx
|
|
11453
11783
|
);
|
|
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;
|
|
11784
|
+
const paragraphTooTallForSinglePage = rawNodeHeightPx > nodeMetrics.pageContentHeightPx + PAGE_OVERFLOW_TOLERANCE_PX;
|
|
11462
11785
|
const keepLinesOverflowSplit = node.style?.keepLines === true && paragraphTooTallForSinglePage;
|
|
11463
11786
|
const keepNextOverflowSplit = node.style?.keepNext === true && paragraphTooTallForSinglePage;
|
|
11464
11787
|
const forceOverflowSplit = keepLinesOverflowSplit || keepNextOverflowSplit;
|
|
11465
|
-
|
|
11788
|
+
const nodeIsWithinCommittedKeepNextChain = nodeIndex <= committedKeepNextChainEndNodeIndex;
|
|
11789
|
+
if (forceOverflowSplit && !nodeIsWithinCommittedKeepNextChain && pageConsumedHeightPx > 0 && currentPageSegments.length > 0) {
|
|
11466
11790
|
startNextPage();
|
|
11467
11791
|
pageConsumedHeightPx = 0;
|
|
11468
11792
|
previousParagraphAfterPx = 0;
|
|
@@ -11475,7 +11799,7 @@ function buildDocumentPageNodeSegments(model, pageContentHeightPx, pageContentWi
|
|
|
11475
11799
|
const collapsedMarginPx = pageConsumedHeightPx > 0 ? Math.min(previousParagraphAfterPx, beforeSpacingPx) : 0;
|
|
11476
11800
|
const collapsedNodeHeightPx = Math.max(
|
|
11477
11801
|
1,
|
|
11478
|
-
|
|
11802
|
+
rawNodeHeightPx - collapsedMarginPx
|
|
11479
11803
|
);
|
|
11480
11804
|
const paragraphSupportsPretextSegmentRendering = Boolean(
|
|
11481
11805
|
paragraphPretextSourceForSegmentRendering
|
|
@@ -11501,7 +11825,7 @@ function buildDocumentPageNodeSegments(model, pageContentHeightPx, pageContentWi
|
|
|
11501
11825
|
}
|
|
11502
11826
|
const collapsedNodeHeightPxAdjusted = Math.max(
|
|
11503
11827
|
1,
|
|
11504
|
-
|
|
11828
|
+
rawNodeHeightPx - collapsedMarginPx
|
|
11505
11829
|
);
|
|
11506
11830
|
const paragraphPretextLineCount = paragraphContainsExplicitLineBreakText(node) || paragraphContainsTabCharacter(node) ? resolveParagraphPretextLayoutForSegmentRendering()?.lineCount : void 0;
|
|
11507
11831
|
const supportsImageParagraphLineSplit = paragraphHasImage2(node) && paragraphSupportsPretextSegmentRendering;
|
|
@@ -11725,7 +12049,8 @@ function buildDocumentPageNodeSegments(model, pageContentHeightPx, pageContentWi
|
|
|
11725
12049
|
continue;
|
|
11726
12050
|
}
|
|
11727
12051
|
let requiredHeightPx = collapsedNodeHeightPxAdjusted;
|
|
11728
|
-
|
|
12052
|
+
let keepNextChainEndNodeIndex = -1;
|
|
12053
|
+
if (node.style?.keepNext === true && !nodeIsWithinCommittedKeepNextChain && paragraphHasVisibleText2(node)) {
|
|
11729
12054
|
let chainCursor = nodeIndex;
|
|
11730
12055
|
let chainPreviousParagraphAfterPx = afterSpacingPx;
|
|
11731
12056
|
while (chainCursor < model.nodes.length - 1) {
|
|
@@ -11785,6 +12110,7 @@ function buildDocumentPageNodeSegments(model, pageContentHeightPx, pageContentWi
|
|
|
11785
12110
|
);
|
|
11786
12111
|
chainPreviousParagraphAfterPx = nextAfterSpacingPx;
|
|
11787
12112
|
}
|
|
12113
|
+
keepNextChainEndNodeIndex = chainCursor;
|
|
11788
12114
|
}
|
|
11789
12115
|
const remainingHeightPx = currentPageContentHeightPx - pageConsumedHeightPx;
|
|
11790
12116
|
const canKeepTrailingSectionTailOnCurrentPage = shouldKeepTrailingSectionTailOnCurrentPage(
|
|
@@ -11826,11 +12152,11 @@ function buildDocumentPageNodeSegments(model, pageContentHeightPx, pageContentWi
|
|
|
11826
12152
|
nodeMetrics
|
|
11827
12153
|
);
|
|
11828
12154
|
}
|
|
12155
|
+
if (pageConsumedHeightPx === 0 && keepNextChainEndNodeIndex > nodeIndex) {
|
|
12156
|
+
committedKeepNextChainEndNodeIndex = keepNextChainEndNodeIndex;
|
|
12157
|
+
}
|
|
11829
12158
|
currentPageSegments.push({ nodeIndex });
|
|
11830
|
-
const effectiveNodeHeightPx =
|
|
11831
|
-
pageConsumedHeightPx > 0 ? collapsedNodeHeightPx : rawNodeHeightPx,
|
|
11832
|
-
coverFootprintPx
|
|
11833
|
-
);
|
|
12159
|
+
const effectiveNodeHeightPx = pageConsumedHeightPx > 0 ? collapsedNodeHeightPx : rawNodeHeightPx;
|
|
11834
12160
|
pageConsumedHeightPx += effectiveNodeHeightPx;
|
|
11835
12161
|
previousParagraphAfterPx = afterSpacingPx;
|
|
11836
12162
|
continue;
|
|
@@ -12637,11 +12963,15 @@ function paragraphLineHeight(paragraph, docGridLinePitchPx, disableDocGridSnap =
|
|
|
12637
12963
|
disableDocGridSnap
|
|
12638
12964
|
)}px`;
|
|
12639
12965
|
}
|
|
12640
|
-
const
|
|
12641
|
-
|
|
12642
|
-
|
|
12643
|
-
|
|
12644
|
-
|
|
12966
|
+
const resolvedAutoMultiple = resolveAutoLineSpacingMultiple(
|
|
12967
|
+
lineTwips,
|
|
12968
|
+
DEFAULT_PARAGRAPH_LINE_MULTIPLE
|
|
12969
|
+
);
|
|
12970
|
+
const lineMultiple = paragraphRendersTextFreeLine(paragraph) ? Math.max(
|
|
12971
|
+
MIN_AUTO_LINE_MULTIPLE,
|
|
12972
|
+
Number((resolvedAutoMultiple * singleLineScale).toFixed(3))
|
|
12973
|
+
) : calibrateAutoLineSpacingMultiple(
|
|
12974
|
+
resolvedAutoMultiple,
|
|
12645
12975
|
baseFontFamily,
|
|
12646
12976
|
singleLineScale
|
|
12647
12977
|
);
|
|
@@ -12984,9 +13314,7 @@ function paragraphBlockStyle(paragraph, numberingDefinitions, headingStyles, doc
|
|
|
12984
13314
|
const suppressTocNumberingTextIndent = isTableOfContentsParagraph(paragraph) && paragraphHasNumbering(paragraph);
|
|
12985
13315
|
const suppressIndentForFloatingAnchorOnlyParagraph = paragraphIsFloatingImageAnchorOnly(paragraph);
|
|
12986
13316
|
const suppressStackingContextForBehindTextAnchorOnlyParagraph = paragraphIsBehindTextAbsoluteFloatingImageAnchorOnly(paragraph);
|
|
12987
|
-
const
|
|
12988
|
-
const textBearingAbsoluteFloatingTextBoxFootprintPx = paragraphTextBearingAbsoluteFloatingTextBoxFootprintPx(paragraph);
|
|
12989
|
-
const reservedMinHeightPx = suppressFlowFootprintForBehindTextAnchorOnlyParagraph ? void 0 : textBearingAbsoluteFloatingTextBoxFootprintPx > 0 ? textBearingAbsoluteFloatingTextBoxFootprintPx : paragraphIsEffectivelyEmpty(paragraph) ? estimateParagraphLineHeightPx(
|
|
13317
|
+
const reservedMinHeightPx = paragraphIsEffectivelyEmpty(paragraph) ? estimateParagraphLineHeightPx(
|
|
12990
13318
|
paragraph,
|
|
12991
13319
|
docGridLinePitchPx,
|
|
12992
13320
|
disableDocGridSnap
|
|
@@ -13005,15 +13333,13 @@ function paragraphBlockStyle(paragraph, numberingDefinitions, headingStyles, doc
|
|
|
13005
13333
|
// line-box strut tracks the actual content instead of the browser's
|
|
13006
13334
|
// 16px default, which inflates lines for sub-12pt paragraphs.
|
|
13007
13335
|
fontSize: `${paragraphBaseFontSizePx(paragraph)}px`,
|
|
13008
|
-
lineHeight:
|
|
13009
|
-
|
|
13010
|
-
|
|
13011
|
-
|
|
13012
|
-
|
|
13013
|
-
|
|
13014
|
-
|
|
13015
|
-
marginBottom: afterSpacing
|
|
13016
|
-
},
|
|
13336
|
+
lineHeight: paragraphLineHeight(
|
|
13337
|
+
paragraph,
|
|
13338
|
+
docGridLinePitchPx,
|
|
13339
|
+
disableDocGridSnap
|
|
13340
|
+
),
|
|
13341
|
+
marginTop: beforeSpacing,
|
|
13342
|
+
marginBottom: afterSpacing,
|
|
13017
13343
|
marginLeft: suppressIndentForFloatingAnchorOnlyParagraph ? 0 : leftIndent,
|
|
13018
13344
|
marginRight: suppressIndentForFloatingAnchorOnlyParagraph ? 0 : rightIndent,
|
|
13019
13345
|
backgroundColor: paragraph.style?.backgroundColor,
|
|
@@ -14744,7 +15070,8 @@ function renderParagraphRuns(paragraph, keyPrefix, documentTheme = "light", numb
|
|
|
14744
15070
|
const resolveNextTabWidthPx = () => resolveTabSpacerWidthPx(
|
|
14745
15071
|
tabStopPositionsPx,
|
|
14746
15072
|
approximateLineWidthPx,
|
|
14747
|
-
fallbackTabWidthPx
|
|
15073
|
+
fallbackTabWidthPx,
|
|
15074
|
+
checkboxChoiceRow
|
|
14748
15075
|
);
|
|
14749
15076
|
const appendPlainTextWithSoftBreakControl = (target, keySeed, text, style, measureStyle) => {
|
|
14750
15077
|
const shouldControlSoftBreakStretch = paragraph.style?.align === "justify" && text.includes("\n");
|
|
@@ -22822,12 +23149,32 @@ function ensureDocxViewerPageSurfaceRegistry(editor) {
|
|
|
22822
23149
|
if (!registry) {
|
|
22823
23150
|
registry = {
|
|
22824
23151
|
pageElements: /* @__PURE__ */ new Map(),
|
|
23152
|
+
pageContentKeys: /* @__PURE__ */ new Map(),
|
|
22825
23153
|
listeners: /* @__PURE__ */ new Set()
|
|
22826
23154
|
};
|
|
22827
23155
|
docxViewerPageSurfaceRegistryByEditor.set(owner, registry);
|
|
22828
23156
|
}
|
|
22829
23157
|
return registry;
|
|
22830
23158
|
}
|
|
23159
|
+
function syncDocxViewerPageSurfaceContentKeys(editor, contentKeysByPage) {
|
|
23160
|
+
const registry = ensureDocxViewerPageSurfaceRegistry(editor);
|
|
23161
|
+
let changed = false;
|
|
23162
|
+
contentKeysByPage.forEach((contentKey, pageIndex) => {
|
|
23163
|
+
if (registry.pageContentKeys.get(pageIndex) !== contentKey) {
|
|
23164
|
+
registry.pageContentKeys.set(pageIndex, contentKey);
|
|
23165
|
+
changed = true;
|
|
23166
|
+
}
|
|
23167
|
+
});
|
|
23168
|
+
registry.pageContentKeys.forEach((_, pageIndex) => {
|
|
23169
|
+
if (pageIndex >= contentKeysByPage.length) {
|
|
23170
|
+
registry.pageContentKeys.delete(pageIndex);
|
|
23171
|
+
changed = true;
|
|
23172
|
+
}
|
|
23173
|
+
});
|
|
23174
|
+
if (changed) {
|
|
23175
|
+
notifyDocxViewerPageSurfaceSubscribers(registry);
|
|
23176
|
+
}
|
|
23177
|
+
}
|
|
22831
23178
|
function subscribeDocxViewerPageSurfaces(editor, listener) {
|
|
22832
23179
|
const registry = ensureDocxViewerPageSurfaceRegistry(editor);
|
|
22833
23180
|
registry.listeners.add(listener);
|
|
@@ -22891,62 +23238,8 @@ function resolveDocxViewerPageSurfaceSize(element, fallbackWidthPx, fallbackHeig
|
|
|
22891
23238
|
heightPx: Math.max(1, Math.round(fallbackHeightPx))
|
|
22892
23239
|
};
|
|
22893
23240
|
}
|
|
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
|
-
}
|
|
23241
|
+
var DOCX_THUMBNAIL_SURFACE_CACHE_MAX_ENTRIES = 32;
|
|
23242
|
+
var DOCX_THUMBNAIL_MIN_RASTER_INTERVAL_MS = 200;
|
|
22950
23243
|
function resolveDocxPageThumbnailResolution(options) {
|
|
22951
23244
|
const safeSourceWidthPx = Math.max(1, Math.round(options.sourceWidthPx));
|
|
22952
23245
|
const safeSourceHeightPx = Math.max(1, Math.round(options.sourceHeightPx));
|
|
@@ -23020,8 +23313,51 @@ function useDocxPageThumbnails(editor, options = {}) {
|
|
|
23020
23313
|
},
|
|
23021
23314
|
[]
|
|
23022
23315
|
);
|
|
23316
|
+
const thumbnailSurfaceCacheRef = React.useRef(void 0);
|
|
23317
|
+
const thumbnailRasterQueueRef = React.useRef(void 0);
|
|
23318
|
+
const lastPaintedThumbnailKeyByCanvasRef = React.useRef(
|
|
23319
|
+
/* @__PURE__ */ new WeakMap()
|
|
23320
|
+
);
|
|
23321
|
+
const ensureThumbnailSurfaceCache = React.useCallback(() => {
|
|
23322
|
+
if (!thumbnailSurfaceCacheRef.current) {
|
|
23323
|
+
thumbnailSurfaceCacheRef.current = new DocxThumbnailSurfaceCache(
|
|
23324
|
+
DOCX_THUMBNAIL_SURFACE_CACHE_MAX_ENTRIES
|
|
23325
|
+
);
|
|
23326
|
+
}
|
|
23327
|
+
return thumbnailSurfaceCacheRef.current;
|
|
23328
|
+
}, []);
|
|
23329
|
+
const ensureThumbnailRasterQueue = React.useCallback(() => {
|
|
23330
|
+
if (!thumbnailRasterQueueRef.current) {
|
|
23331
|
+
thumbnailRasterQueueRef.current = new SerialIdleTaskQueue({
|
|
23332
|
+
minTaskIntervalMs: DOCX_THUMBNAIL_MIN_RASTER_INTERVAL_MS
|
|
23333
|
+
});
|
|
23334
|
+
}
|
|
23335
|
+
return thumbnailRasterQueueRef.current;
|
|
23336
|
+
}, []);
|
|
23337
|
+
React.useEffect(() => {
|
|
23338
|
+
thumbnailSurfaceCacheRef.current?.clear();
|
|
23339
|
+
thumbnailRasterQueueRef.current?.clear();
|
|
23340
|
+
lastPaintedThumbnailKeyByCanvasRef.current = /* @__PURE__ */ new WeakMap();
|
|
23341
|
+
}, [editor.documentLoadNonce, pageSurfaceRegistryOwner]);
|
|
23342
|
+
const thumbnailResolutionOptionsKey = React.useMemo(() => {
|
|
23343
|
+
const bounds = options.resolution;
|
|
23344
|
+
const boundsKey = typeof bounds === "number" ? `n${bounds}` : bounds ? `b${bounds.maxWidth ?? ""}x${bounds.maxHeight ?? ""}` : "";
|
|
23345
|
+
return `${boundsKey}|${options.maxWidthPx ?? ""}|${options.maxHeightPx ?? ""}|${options.pixelRatio ?? ""}`;
|
|
23346
|
+
}, [
|
|
23347
|
+
options.maxHeightPx,
|
|
23348
|
+
options.maxWidthPx,
|
|
23349
|
+
options.pixelRatio,
|
|
23350
|
+
options.resolution
|
|
23351
|
+
]);
|
|
23352
|
+
const thumbnailSkipKeyForPage = React.useCallback(
|
|
23353
|
+
(pageIndex) => {
|
|
23354
|
+
const contentKey = pageSurfaceRegistry.pageContentKeys.get(pageIndex);
|
|
23355
|
+
return contentKey === void 0 ? void 0 : `${contentKey}|${editor.documentTheme}|${thumbnailResolutionOptionsKey}`;
|
|
23356
|
+
},
|
|
23357
|
+
[editor.documentTheme, pageSurfaceRegistry, thumbnailResolutionOptionsKey]
|
|
23358
|
+
);
|
|
23023
23359
|
const renderPageThumbnailToCanvas = React.useCallback(
|
|
23024
|
-
async (pageIndex, canvas) => {
|
|
23360
|
+
async (pageIndex, canvas, renderOptions) => {
|
|
23025
23361
|
if (options.disabled) {
|
|
23026
23362
|
return;
|
|
23027
23363
|
}
|
|
@@ -23029,63 +23365,101 @@ function useDocxPageThumbnails(editor, options = {}) {
|
|
|
23029
23365
|
if (!targetCanvas) {
|
|
23030
23366
|
return;
|
|
23031
23367
|
}
|
|
23032
|
-
const pageElement =
|
|
23368
|
+
const pageElement = pageSurfaceRegistry.pageElements.get(pageIndex);
|
|
23033
23369
|
if (!pageElement || !pageElement.isConnected) {
|
|
23034
23370
|
updatePageThumbnailState(pageIndex, "unavailable");
|
|
23035
23371
|
return;
|
|
23036
23372
|
}
|
|
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
|
-
});
|
|
23373
|
+
const force = renderOptions?.force === true;
|
|
23374
|
+
const lastPaintedKey = lastPaintedThumbnailKeyByCanvasRef.current.get(targetCanvas);
|
|
23375
|
+
if (!force && lastPaintedKey !== void 0 && lastPaintedKey === thumbnailSkipKeyForPage(pageIndex)) {
|
|
23376
|
+
updatePageThumbnailState(pageIndex, "ready");
|
|
23377
|
+
return;
|
|
23378
|
+
}
|
|
23050
23379
|
updatePageThumbnailState(pageIndex, "rendering");
|
|
23051
|
-
|
|
23052
|
-
|
|
23053
|
-
|
|
23380
|
+
await ensureThumbnailRasterQueue().enqueue(targetCanvas, async () => {
|
|
23381
|
+
const livePageElement = pageSurfaceRegistry.pageElements.get(pageIndex);
|
|
23382
|
+
if (!livePageElement || !livePageElement.isConnected) {
|
|
23383
|
+
updatePageThumbnailState(pageIndex, "unavailable");
|
|
23384
|
+
return;
|
|
23385
|
+
}
|
|
23386
|
+
const runSkipKey = thumbnailSkipKeyForPage(pageIndex);
|
|
23387
|
+
const sourceSize = resolveDocxViewerPageSurfaceSize(
|
|
23388
|
+
livePageElement,
|
|
23389
|
+
fallbackLayout.pageWidthPx,
|
|
23390
|
+
fallbackLayout.pageHeightPx
|
|
23391
|
+
);
|
|
23392
|
+
const resolution = resolveDocxPageThumbnailResolution({
|
|
23054
23393
|
sourceWidthPx: sourceSize.widthPx,
|
|
23055
23394
|
sourceHeightPx: sourceSize.heightPx,
|
|
23056
|
-
|
|
23057
|
-
|
|
23058
|
-
|
|
23059
|
-
|
|
23060
|
-
pixelHeightPx: resolution.pixelHeightPx
|
|
23395
|
+
resolution: options.resolution,
|
|
23396
|
+
maxWidthPx: options.maxWidthPx,
|
|
23397
|
+
maxHeightPx: options.maxHeightPx,
|
|
23398
|
+
pixelRatio: options.pixelRatio
|
|
23061
23399
|
});
|
|
23062
|
-
|
|
23063
|
-
|
|
23064
|
-
|
|
23065
|
-
|
|
23066
|
-
|
|
23067
|
-
|
|
23068
|
-
|
|
23069
|
-
|
|
23400
|
+
const surfaceKey = runSkipKey === void 0 ? void 0 : `${runSkipKey}|${sourceSize.widthPx}x${sourceSize.heightPx}|${resolution.pixelWidthPx}x${resolution.pixelHeightPx}`;
|
|
23401
|
+
const surfaceCache = ensureThumbnailSurfaceCache();
|
|
23402
|
+
try {
|
|
23403
|
+
let surface = !force && surfaceKey !== void 0 ? surfaceCache.get(surfaceKey) : void 0;
|
|
23404
|
+
if (!surface) {
|
|
23405
|
+
surface = await rasterizeDocxThumbnailSurface({
|
|
23406
|
+
pageElement: livePageElement,
|
|
23407
|
+
sourceWidthPx: sourceSize.widthPx,
|
|
23408
|
+
sourceHeightPx: sourceSize.heightPx,
|
|
23409
|
+
widthPx: resolution.widthPx,
|
|
23410
|
+
heightPx: resolution.heightPx,
|
|
23411
|
+
pixelWidthPx: resolution.pixelWidthPx,
|
|
23412
|
+
pixelHeightPx: resolution.pixelHeightPx
|
|
23413
|
+
});
|
|
23414
|
+
if (surfaceKey !== void 0) {
|
|
23415
|
+
surfaceCache.set(surfaceKey, surface);
|
|
23416
|
+
}
|
|
23417
|
+
}
|
|
23418
|
+
blitDocxThumbnailSurface(surface, targetCanvas, resolution);
|
|
23419
|
+
if (runSkipKey !== void 0) {
|
|
23420
|
+
lastPaintedThumbnailKeyByCanvasRef.current.set(
|
|
23421
|
+
targetCanvas,
|
|
23422
|
+
runSkipKey
|
|
23423
|
+
);
|
|
23424
|
+
}
|
|
23425
|
+
updatePageThumbnailState(pageIndex, "ready");
|
|
23426
|
+
} catch (error) {
|
|
23427
|
+
updatePageThumbnailState(
|
|
23428
|
+
pageIndex,
|
|
23429
|
+
"error",
|
|
23430
|
+
error instanceof Error ? error : new Error("Failed to render DOCX page thumbnail.")
|
|
23431
|
+
);
|
|
23432
|
+
}
|
|
23433
|
+
});
|
|
23070
23434
|
},
|
|
23071
23435
|
[
|
|
23436
|
+
ensureThumbnailRasterQueue,
|
|
23437
|
+
ensureThumbnailSurfaceCache,
|
|
23072
23438
|
fallbackLayout.pageHeightPx,
|
|
23073
23439
|
fallbackLayout.pageWidthPx,
|
|
23074
|
-
mountedPageElements,
|
|
23075
23440
|
options.disabled,
|
|
23076
23441
|
options.resolution,
|
|
23077
23442
|
options.maxHeightPx,
|
|
23078
23443
|
options.maxWidthPx,
|
|
23079
23444
|
options.pixelRatio,
|
|
23445
|
+
pageSurfaceRegistry,
|
|
23446
|
+
thumbnailSkipKeyForPage,
|
|
23080
23447
|
updatePageThumbnailState
|
|
23081
23448
|
]
|
|
23082
23449
|
);
|
|
23083
|
-
const
|
|
23084
|
-
|
|
23085
|
-
|
|
23086
|
-
|
|
23087
|
-
|
|
23088
|
-
|
|
23450
|
+
const requestAttachedThumbnailRenders = React.useCallback(
|
|
23451
|
+
async (renderOptions) => {
|
|
23452
|
+
const tasks = [...attachedCanvasByPageRef.current.keys()].map(
|
|
23453
|
+
(pageIndex) => renderPageThumbnailToCanvas(pageIndex, void 0, renderOptions)
|
|
23454
|
+
);
|
|
23455
|
+
await Promise.all(tasks);
|
|
23456
|
+
},
|
|
23457
|
+
[renderPageThumbnailToCanvas]
|
|
23458
|
+
);
|
|
23459
|
+
const rerenderAttachedThumbnails = React.useCallback(
|
|
23460
|
+
async () => requestAttachedThumbnailRenders({ force: true }),
|
|
23461
|
+
[requestAttachedThumbnailRenders]
|
|
23462
|
+
);
|
|
23089
23463
|
const renderPageThumbnailToCanvasRef = React.useRef(
|
|
23090
23464
|
renderPageThumbnailToCanvas
|
|
23091
23465
|
);
|
|
@@ -23097,7 +23471,7 @@ function useDocxPageThumbnails(editor, options = {}) {
|
|
|
23097
23471
|
renderToCanvasCallbacksRef.current.clear();
|
|
23098
23472
|
}, [pageSurfaceRegistryOwner]);
|
|
23099
23473
|
React.useEffect(() => {
|
|
23100
|
-
void
|
|
23474
|
+
void requestAttachedThumbnailRenders();
|
|
23101
23475
|
}, [
|
|
23102
23476
|
editor.documentLoadNonce,
|
|
23103
23477
|
editor.documentTheme,
|
|
@@ -23108,7 +23482,7 @@ function useDocxPageThumbnails(editor, options = {}) {
|
|
|
23108
23482
|
options.maxHeightPx,
|
|
23109
23483
|
options.maxWidthPx,
|
|
23110
23484
|
options.pixelRatio,
|
|
23111
|
-
|
|
23485
|
+
requestAttachedThumbnailRenders
|
|
23112
23486
|
]);
|
|
23113
23487
|
const thumbnails = React.useMemo(() => {
|
|
23114
23488
|
const totalPages = Math.max(1, editor.totalPages);
|
|
@@ -25498,6 +25872,42 @@ function DocxEditorViewer({
|
|
|
25498
25872
|
pageNodeSegmentsByPage,
|
|
25499
25873
|
primarySectionPropertiesXml
|
|
25500
25874
|
]);
|
|
25875
|
+
const pageThumbnailContentKeysByPage = React.useMemo(() => {
|
|
25876
|
+
const metadataSignature = docModelThumbnailMetadataSignature(
|
|
25877
|
+
editor.model.metadata
|
|
25878
|
+
);
|
|
25879
|
+
return pageNodeSegmentsByPage.map((pageSegments, pageIndex) => {
|
|
25880
|
+
const sectionInfo = pageSectionInfoByIndex[pageIndex];
|
|
25881
|
+
let nodeSignatures = "";
|
|
25882
|
+
for (const segment of pageSegments) {
|
|
25883
|
+
nodeSignatures += docNodeContentSignature(
|
|
25884
|
+
editor.model.nodes[segment.nodeIndex]
|
|
25885
|
+
);
|
|
25886
|
+
nodeSignatures += ",";
|
|
25887
|
+
}
|
|
25888
|
+
return [
|
|
25889
|
+
editor.documentLoadNonce,
|
|
25890
|
+
trackedChangesEnabled ? "tc1" : "tc0",
|
|
25891
|
+
metadataSignature,
|
|
25892
|
+
sectionInfo ? `${sectionInfo.sectionIndex}.${sectionInfo.pageNumber}` : "s?",
|
|
25893
|
+
pageNodeSegmentIdentityKeysByPage[pageIndex] ?? "",
|
|
25894
|
+
nodeSignatures
|
|
25895
|
+
].join("|");
|
|
25896
|
+
});
|
|
25897
|
+
}, [
|
|
25898
|
+
editor.documentLoadNonce,
|
|
25899
|
+
editor.model,
|
|
25900
|
+
pageNodeSegmentIdentityKeysByPage,
|
|
25901
|
+
pageNodeSegmentsByPage,
|
|
25902
|
+
pageSectionInfoByIndex,
|
|
25903
|
+
trackedChangesEnabled
|
|
25904
|
+
]);
|
|
25905
|
+
React.useEffect(() => {
|
|
25906
|
+
syncDocxViewerPageSurfaceContentKeys(
|
|
25907
|
+
editor,
|
|
25908
|
+
pageThumbnailContentKeysByPage
|
|
25909
|
+
);
|
|
25910
|
+
}, [pageSurfaceRegistryOwner, pageThumbnailContentKeysByPage]);
|
|
25501
25911
|
const resolveStyleRefFieldValueForPage = React.useMemo(() => {
|
|
25502
25912
|
const valueCache = /* @__PURE__ */ new Map();
|
|
25503
25913
|
const nodes = editor.model.nodes;
|
|
@@ -25756,6 +26166,14 @@ function DocxEditorViewer({
|
|
|
25756
26166
|
overscan: pageVirtualizationOverscan
|
|
25757
26167
|
});
|
|
25758
26168
|
const internalPageVirtualizer = internalVirtualScrollUsesWindow ? internalWindowPageVirtualizer : internalElementPageVirtualizer;
|
|
26169
|
+
React.useLayoutEffect(() => {
|
|
26170
|
+
internalElementPageVirtualizer.measure();
|
|
26171
|
+
internalWindowPageVirtualizer.measure();
|
|
26172
|
+
}, [
|
|
26173
|
+
estimateVirtualPageSize,
|
|
26174
|
+
internalElementPageVirtualizer,
|
|
26175
|
+
internalWindowPageVirtualizer
|
|
26176
|
+
]);
|
|
25759
26177
|
const internalVirtualItems = internalPageVirtualizer.getVirtualItems();
|
|
25760
26178
|
const internalVisiblePageRange = React.useMemo(() => {
|
|
25761
26179
|
if (!internalPageVirtualizationEnabled) {
|
|
@@ -25798,8 +26216,8 @@ function DocxEditorViewer({
|
|
|
25798
26216
|
return internalVisiblePageRange;
|
|
25799
26217
|
}
|
|
25800
26218
|
const scrollDirection = internalPageVirtualizer.scrollDirection;
|
|
25801
|
-
const renderPreviousPage = scrollDirection !== "
|
|
25802
|
-
const renderNextPage = scrollDirection
|
|
26219
|
+
const renderPreviousPage = scrollDirection !== "forward";
|
|
26220
|
+
const renderNextPage = scrollDirection !== "backward";
|
|
25803
26221
|
const startPageIndex = clampNumber(
|
|
25804
26222
|
internalVisiblePageRange.startPageIndex - (renderPreviousPage ? LARGE_TABLE_PAGE_ADJACENT_RENDER_COUNT : 0),
|
|
25805
26223
|
0,
|
|
@@ -33214,6 +33632,7 @@ function DocxEditorViewer({
|
|
|
33214
33632
|
"span",
|
|
33215
33633
|
{
|
|
33216
33634
|
contentEditable: false,
|
|
33635
|
+
...{ [DOCX_THUMBNAIL_EXCLUDE_ATTRIBUTE]: "true" },
|
|
33217
33636
|
style: {
|
|
33218
33637
|
position: "absolute",
|
|
33219
33638
|
left: rect.left,
|
|
@@ -33236,6 +33655,7 @@ function DocxEditorViewer({
|
|
|
33236
33655
|
"span",
|
|
33237
33656
|
{
|
|
33238
33657
|
contentEditable: false,
|
|
33658
|
+
...{ [DOCX_THUMBNAIL_EXCLUDE_ATTRIBUTE]: "true" },
|
|
33239
33659
|
style: {
|
|
33240
33660
|
position: "absolute",
|
|
33241
33661
|
left: caretRect.left,
|
|
@@ -33605,7 +34025,10 @@ function DocxEditorViewer({
|
|
|
33605
34025
|
Math.round(options?.pageFlowTopPx ?? 0)
|
|
33606
34026
|
);
|
|
33607
34027
|
const bodyParagraphOriginLeftPx = interactiveBodyFloatingPageOriginPx ? paragraphPageLayout.marginsPx.left : void 0;
|
|
33608
|
-
const bodyParagraphOriginTopPx = interactiveBodyFloatingPageOriginPx ?
|
|
34028
|
+
const bodyParagraphOriginTopPx = interactiveBodyFloatingPageOriginPx ? paragraphActsAsPageAnchoredCoverOverlayHost(
|
|
34029
|
+
paragraph,
|
|
34030
|
+
paragraphPageLayout
|
|
34031
|
+
) ? paragraphPageLayout.marginsPx.top + paragraphPageFlowTopPx : 0 : void 0;
|
|
33609
34032
|
const resizedWidthPxByImageIndex = /* @__PURE__ */ new Map();
|
|
33610
34033
|
const resizedHeightPxByImageIndex = /* @__PURE__ */ new Map();
|
|
33611
34034
|
const movePreviewByImageIndex = /* @__PURE__ */ new Map();
|
|
@@ -36439,13 +36862,6 @@ function DocxEditorViewer({
|
|
|
36439
36862
|
options?.pageFlowForeignExclusions ?? []
|
|
36440
36863
|
)
|
|
36441
36864
|
);
|
|
36442
|
-
const leadingCoverLayoutSpacer = paragraphActsAsLeadingCoverLayoutSpacer(
|
|
36443
|
-
editor.model,
|
|
36444
|
-
nodeIndex,
|
|
36445
|
-
node,
|
|
36446
|
-
paragraphContentWidthPx,
|
|
36447
|
-
resolvedPageLayout.pageHeightPx - resolvedPageLayout.marginsPx.top - resolvedPageLayout.marginsPx.bottom
|
|
36448
|
-
);
|
|
36449
36865
|
const beforeSpacingPx = effectiveParagraphBeforeSpacingPx(
|
|
36450
36866
|
editor.model,
|
|
36451
36867
|
nodeIndex,
|
|
@@ -36499,14 +36915,12 @@ function DocxEditorViewer({
|
|
|
36499
36915
|
marginTop: (typeof baseParagraphStyle.marginTop === "number" ? baseParagraphStyle.marginTop : 0) - (pageAnchoredCoverOverlayParagraph ? resolvedPageLayout.marginsPx.top : 0),
|
|
36500
36916
|
marginLeft: -resolvedPageLayout.marginsPx.left,
|
|
36501
36917
|
marginRight: -resolvedPageLayout.marginsPx.right,
|
|
36502
|
-
|
|
36503
|
-
|
|
36504
|
-
|
|
36918
|
+
// A cover-overlay host is remapped to the page surface and must
|
|
36919
|
+
// not displace flow; an ordinary anchor host still occupies its
|
|
36920
|
+
// one-line paragraph box (Word semantics).
|
|
36921
|
+
...pageAnchoredCoverOverlayParagraph ? { minHeight: 0, height: 0, lineHeight: 0 } : void 0,
|
|
36505
36922
|
overflow: "visible"
|
|
36506
36923
|
} : 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
36924
|
// Carry the paragraph's run font on the editable host so text typed into
|
|
36511
36925
|
// it (which is a bare, not-yet-committed text node, not a styled run
|
|
36512
36926
|
// span) renders in the same font the committed run will use — i.e. the
|
|
@@ -37541,6 +37955,22 @@ ${currentText.slice(end)}`;
|
|
|
37541
37955
|
const rowSpanValue = cell.style?.rowSpan && cell.style.rowSpan > 1 ? cell.style.rowSpan : 1;
|
|
37542
37956
|
const colSpan = colSpanValue > 1 ? colSpanValue : void 0;
|
|
37543
37957
|
const rowSpan = rowSpanValue > 1 ? rowSpanValue : void 0;
|
|
37958
|
+
const exactRowSpanRows = node.rows.slice(
|
|
37959
|
+
rowIndex,
|
|
37960
|
+
rowIndex + rowSpanValue
|
|
37961
|
+
);
|
|
37962
|
+
const exactRowSpanClipHeightPx = exactRowSpanRows.length > 0 && exactRowSpanRows.every((spannedRow, rowOffset) => {
|
|
37963
|
+
const spannedHeightPx = rowHeightsPx[rowIndex + rowOffset];
|
|
37964
|
+
return spannedRow.style?.heightRule === "exact" && Number.isFinite(spannedHeightPx) && spannedHeightPx > 0;
|
|
37965
|
+
}) ? exactRowSpanRows.reduce(
|
|
37966
|
+
(sum, _spannedRow, rowOffset) => sum + Math.max(
|
|
37967
|
+
MIN_PARAGRAPH_LINE_HEIGHT_PX,
|
|
37968
|
+
Math.round(
|
|
37969
|
+
rowHeightsPx[rowIndex + rowOffset]
|
|
37970
|
+
)
|
|
37971
|
+
),
|
|
37972
|
+
0
|
|
37973
|
+
) : void 0;
|
|
37544
37974
|
const startColumnIndex = columnCursor;
|
|
37545
37975
|
const boundaryColumnIndex = startColumnIndex + colSpanValue - 1;
|
|
37546
37976
|
columnCursor += colSpanValue;
|
|
@@ -38659,12 +39089,11 @@ ${currentText.slice(end)}`;
|
|
|
38659
39089
|
style: {
|
|
38660
39090
|
display: "grid",
|
|
38661
39091
|
gap: 0,
|
|
38662
|
-
//
|
|
38663
|
-
//
|
|
38664
|
-
//
|
|
38665
|
-
|
|
38666
|
-
|
|
38667
|
-
maxHeight: resolvedRowHeightStyle.height,
|
|
39092
|
+
// Without the clip the row balloons to fit
|
|
39093
|
+
// content (height on a <tr>/<td> is only
|
|
39094
|
+
// ever a minimum).
|
|
39095
|
+
...exactRowSpanClipHeightPx !== void 0 && !isSlicedRow ? {
|
|
39096
|
+
maxHeight: `${exactRowSpanClipHeightPx}px`,
|
|
38668
39097
|
overflow: "hidden"
|
|
38669
39098
|
} : void 0
|
|
38670
39099
|
},
|
|
@@ -40451,11 +40880,27 @@ ${currentText.slice(end)}`;
|
|
|
40451
40880
|
currentGroup.segments.push(segment);
|
|
40452
40881
|
return;
|
|
40453
40882
|
}
|
|
40883
|
+
if (currentGroup && parseSectionStartType(
|
|
40884
|
+
documentSections[currentSectionIndex]?.sectionPropertiesXml
|
|
40885
|
+
) === "nextcolumn") {
|
|
40886
|
+
const previousColumns = sectionColumnsBySectionIndex[currentGroup.sectionIndex];
|
|
40887
|
+
const nextColumns = sectionColumnsBySectionIndex[currentSectionIndex];
|
|
40888
|
+
const sameGeometry = previousColumns && nextColumns && previousColumns.count === nextColumns.count && Math.abs(
|
|
40889
|
+
previousColumns.gapPx - nextColumns.gapPx
|
|
40890
|
+
) <= 2 && JSON.stringify(previousColumns.widthsPx ?? null) === JSON.stringify(nextColumns.widthsPx ?? null);
|
|
40891
|
+
if (sameGeometry) {
|
|
40892
|
+
currentGroup.segments.push(segment);
|
|
40893
|
+
return;
|
|
40894
|
+
}
|
|
40895
|
+
}
|
|
40454
40896
|
sectionGroups.push({
|
|
40455
40897
|
sectionIndex: currentSectionIndex,
|
|
40456
40898
|
segments: [segment]
|
|
40457
40899
|
});
|
|
40458
40900
|
});
|
|
40901
|
+
if (typeof window !== "undefined" && window.__docxDebugGroups) {
|
|
40902
|
+
console.log("[groups]", pageIndex, JSON.stringify(sectionGroups.map((g) => ({ s: g.sectionIndex, n: g.segments.map((x) => x.nodeIndex) }))));
|
|
40903
|
+
}
|
|
40459
40904
|
return sectionGroups.map((group, groupIndex) => {
|
|
40460
40905
|
const sectionColumns = sectionColumnsBySectionIndex[group.sectionIndex];
|
|
40461
40906
|
const isLastGroupOnPage = groupIndex === sectionGroups.length - 1;
|
|
@@ -40624,7 +41069,7 @@ ${currentText.slice(end)}`;
|
|
|
40624
41069
|
(editor.model.metadata.sections ?? []).filter(
|
|
40625
41070
|
(candidate) => parseSectionStartType(
|
|
40626
41071
|
candidate.sectionPropertiesXml
|
|
40627
|
-
) === "
|
|
41072
|
+
) === "nextcolumn"
|
|
40628
41073
|
).map(
|
|
40629
41074
|
(candidate) => Math.max(
|
|
40630
41075
|
0,
|
|
@@ -42542,6 +42987,7 @@ function collectDocxEstimatedOverflowBreakStartNodeIndexes(model, hardBreakStart
|
|
|
42542
42987
|
let pageConsumedHeightPx = 0;
|
|
42543
42988
|
let previousParagraphAfterPx = 0;
|
|
42544
42989
|
let currentMetricsIndex = 0;
|
|
42990
|
+
let committedKeepNextChainEndNodeIndex = -1;
|
|
42545
42991
|
const suppressSpacingBeforeAfterPageBreak = options?.suppressSpacingBeforeAfterPageBreak ?? false;
|
|
42546
42992
|
let currentPageContentHeightPx = metricsBySection[0]?.pageContentHeightPx ?? fallbackMetrics.pageContentHeightPx;
|
|
42547
42993
|
for (let nodeIndex = 0; nodeIndex < model.nodes.length; nodeIndex += 1) {
|
|
@@ -42579,7 +43025,8 @@ function collectDocxEstimatedOverflowBreakStartNodeIndexes(model, hardBreakStart
|
|
|
42579
43025
|
const collapsedMarginPx = node.type === "paragraph" && pageConsumedHeightPx > 0 ? Math.min(previousParagraphAfterPx, nodeBeforeSpacingPx) : 0;
|
|
42580
43026
|
const collapsedNodeHeightPx = Math.max(1, rawNodeHeightPx - collapsedMarginPx);
|
|
42581
43027
|
let requiredHeightPx = collapsedNodeHeightPx;
|
|
42582
|
-
|
|
43028
|
+
let keepNextChainEndNodeIndex = -1;
|
|
43029
|
+
if (node.type === "paragraph" && node.style?.keepNext === true && nodeIndex > committedKeepNextChainEndNodeIndex && callbacks.paragraphHasVisibleText(node)) {
|
|
42583
43030
|
let chainCursor = nodeIndex;
|
|
42584
43031
|
let chainPreviousParagraphAfterPx = paragraphAfterSpacingPx2(node);
|
|
42585
43032
|
while (chainCursor < model.nodes.length - 1) {
|
|
@@ -42637,6 +43084,7 @@ function collectDocxEstimatedOverflowBreakStartNodeIndexes(model, hardBreakStart
|
|
|
42637
43084
|
);
|
|
42638
43085
|
chainPreviousParagraphAfterPx = paragraphAfterSpacingPx2(nextChainNode);
|
|
42639
43086
|
}
|
|
43087
|
+
keepNextChainEndNodeIndex = chainCursor;
|
|
42640
43088
|
}
|
|
42641
43089
|
const remainingHeightPx = currentPageContentHeightPx - pageConsumedHeightPx;
|
|
42642
43090
|
if (pageConsumedHeightPx > 0 && requiredHeightPx > remainingHeightPx + pageOverflowTolerancePx) {
|
|
@@ -42645,6 +43093,9 @@ function collectDocxEstimatedOverflowBreakStartNodeIndexes(model, hardBreakStart
|
|
|
42645
43093
|
previousParagraphAfterPx = 0;
|
|
42646
43094
|
currentPageContentHeightPx = nodeMetrics.pageContentHeightPx;
|
|
42647
43095
|
}
|
|
43096
|
+
if (pageConsumedHeightPx === 0 && keepNextChainEndNodeIndex > nodeIndex) {
|
|
43097
|
+
committedKeepNextChainEndNodeIndex = keepNextChainEndNodeIndex;
|
|
43098
|
+
}
|
|
42648
43099
|
const effectiveNodeHeightPx = pageConsumedHeightPx > 0 ? collapsedNodeHeightPx : rawNodeHeightPx;
|
|
42649
43100
|
pageConsumedHeightPx += effectiveNodeHeightPx;
|
|
42650
43101
|
previousParagraphAfterPx = node.type === "paragraph" ? paragraphAfterSpacingPx2(node) : 0;
|
|
@@ -42696,6 +43147,7 @@ function buildDocumentPageNodeSegments2(model, pageContentHeightPx, pageContentW
|
|
|
42696
43147
|
let pageConsumedHeightPx = 0;
|
|
42697
43148
|
let previousParagraphAfterPx = 0;
|
|
42698
43149
|
let currentMetricsIndex = 0;
|
|
43150
|
+
let committedKeepNextChainEndNodeIndex = -1;
|
|
42699
43151
|
let currentPageContentHeightPx = resolvePageContentHeightPx(
|
|
42700
43152
|
0,
|
|
42701
43153
|
metricsBySection[0]?.pageContentHeightPx ?? fallbackMetrics.pageContentHeightPx
|
|
@@ -42759,7 +43211,8 @@ function buildDocumentPageNodeSegments2(model, pageContentHeightPx, pageContentW
|
|
|
42759
43211
|
const keepLinesOverflowSplit = node.style?.keepLines === true && paragraphTooTallForSinglePage;
|
|
42760
43212
|
const keepNextOverflowSplit = node.style?.keepNext === true && paragraphTooTallForSinglePage;
|
|
42761
43213
|
const forceOverflowSplit = keepLinesOverflowSplit || keepNextOverflowSplit;
|
|
42762
|
-
|
|
43214
|
+
const nodeIsWithinCommittedKeepNextChain = nodeIndex <= committedKeepNextChainEndNodeIndex;
|
|
43215
|
+
if (forceOverflowSplit && !nodeIsWithinCommittedKeepNextChain && pageConsumedHeightPx > 0 && currentPageSegments.length > 0) {
|
|
42763
43216
|
startNextPage();
|
|
42764
43217
|
pageConsumedHeightPx = 0;
|
|
42765
43218
|
previousParagraphAfterPx = 0;
|
|
@@ -42909,7 +43362,8 @@ function buildDocumentPageNodeSegments2(model, pageContentHeightPx, pageContentW
|
|
|
42909
43362
|
continue;
|
|
42910
43363
|
}
|
|
42911
43364
|
let requiredHeightPx = collapsedNodeHeightPx;
|
|
42912
|
-
|
|
43365
|
+
let keepNextChainEndNodeIndex = -1;
|
|
43366
|
+
if (node.style?.keepNext === true && !nodeIsWithinCommittedKeepNextChain && callbacks.paragraphHasVisibleText(node)) {
|
|
42913
43367
|
let chainCursor = nodeIndex;
|
|
42914
43368
|
let chainPreviousParagraphAfterPx = afterSpacingPx;
|
|
42915
43369
|
while (chainCursor < model.nodes.length - 1) {
|
|
@@ -42967,6 +43421,7 @@ function buildDocumentPageNodeSegments2(model, pageContentHeightPx, pageContentW
|
|
|
42967
43421
|
);
|
|
42968
43422
|
chainPreviousParagraphAfterPx = paragraphAfterSpacingPx2(nextChainNode);
|
|
42969
43423
|
}
|
|
43424
|
+
keepNextChainEndNodeIndex = chainCursor;
|
|
42970
43425
|
}
|
|
42971
43426
|
const remainingHeightPx = currentPageContentHeightPx - pageConsumedHeightPx;
|
|
42972
43427
|
if (pageConsumedHeightPx > 0 && requiredHeightPx > remainingHeightPx + pageOverflowTolerancePx) {
|
|
@@ -42978,6 +43433,9 @@ function buildDocumentPageNodeSegments2(model, pageContentHeightPx, pageContentW
|
|
|
42978
43433
|
nodeMetrics.pageContentHeightPx
|
|
42979
43434
|
);
|
|
42980
43435
|
}
|
|
43436
|
+
if (pageConsumedHeightPx === 0 && keepNextChainEndNodeIndex > nodeIndex) {
|
|
43437
|
+
committedKeepNextChainEndNodeIndex = keepNextChainEndNodeIndex;
|
|
43438
|
+
}
|
|
42981
43439
|
currentPageSegments.push({ nodeIndex });
|
|
42982
43440
|
const effectiveNodeHeightPx = pageConsumedHeightPx > 0 ? collapsedNodeHeightPx : rawNodeHeightPx;
|
|
42983
43441
|
pageConsumedHeightPx += effectiveNodeHeightPx;
|