mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-05-13 16:07:30 +00:00
🩹 fix: PPTX slides fill panel width (drop upscale cap, per-slide scale)
Manual e2e on PR #12934: slides rendered correctly but didn't fill the artifact panel — whitespace on either side. Two issues: 1. The scale was capped at `Math.min(1, available / SLIDE_W)`. On panels wider than 960px, the cap clamped the scale to 1.0 and slides rendered at native size with whitespace on the sides instead of stretching. 2. The scale was computed against the constant `SLIDE_W = 960`, but pptx-preview can emit slides whose `offsetWidth` differs from the init param if the source PPTX has a non-16:9 layout. Per-slide division of `available / nativeW` handles that case. Fix: replace `computeScale()` with two helpers — `availableWidth()` returns the panel content-box width and `scaleFor(nativeW)` returns the per-slide scale. No upscale cap. The slide content is rendered by pptx-preview against its 960×540 canvas using vector text / canvas — scaling up to e.g. 1500px doesn't visibly degrade quality. Tests: regression now also asserts: - `availableWidth()` and `scaleFor()` exist by name - The exact scale formula `availableWidth() / (nativeW || SLIDE_W)` - Negative assertion that `Math.min(1, ...)` is NOT present, so a future "let's add an upscale cap" rewrite can't silently re-introduce the whitespace.
This commit is contained in:
parent
0d0a142ee5
commit
4e2d538b03
2 changed files with 37 additions and 10 deletions
|
|
@ -477,11 +477,23 @@ describe('Office HTML producers', () => {
|
|||
const html = await _internal.pptxToHtmlViaCdn(pptx);
|
||||
/* The wrapper class used by the CSS rules. */
|
||||
expect(html).toContain('lc-slide-wrap');
|
||||
/* The wrap function + the scale computation derived from
|
||||
* `clientWidth / SLIDE_W`. */
|
||||
/* The wrap function + the per-slide scale function. The scale
|
||||
* uses each slide's actual rendered native width (not a
|
||||
* constant) so panels wider than 960px still fill — no
|
||||
* upscale cap means we never leave whitespace on the sides
|
||||
* of the panel. */
|
||||
expect(html).toContain('wrapSlides');
|
||||
expect(html).toContain('SLIDE_W');
|
||||
expect(html).toContain('available / SLIDE_W');
|
||||
expect(html).toContain('scaleFor');
|
||||
expect(html).toContain('availableWidth');
|
||||
/* The scale formula divides available width by the slides
|
||||
* rendered native width — this is the line that ensures full
|
||||
* panel coverage. */
|
||||
expect(html).toContain('availableWidth() / (nativeW || SLIDE_W)');
|
||||
/* Negative assertion: the previous version capped the scale
|
||||
* at 1.0 with `Math.min(1, ...)`, which left whitespace on
|
||||
* panels wider than 960px. The new code must not reintroduce
|
||||
* that cap. */
|
||||
expect(html).not.toContain('Math.min(1');
|
||||
/* Container is hidden during render and revealed by the
|
||||
* `finalize` step so the unscaled flash never reaches the
|
||||
* user. */
|
||||
|
|
|
|||
|
|
@ -1161,10 +1161,21 @@ html, body { margin: 0; padding: 0; background: var(--bg); color: var(--fg); fon
|
|||
container.style.visibility = 'hidden';
|
||||
var previewer = pptxPreview.init(container, { width: SLIDE_W, height: SLIDE_H });
|
||||
|
||||
function computeScale() {
|
||||
var available = (container.clientWidth || window.innerWidth) - 32;
|
||||
if (available <= 0) { available = 600; }
|
||||
return Math.min(1, available / SLIDE_W);
|
||||
function availableWidth() {
|
||||
/* clientWidth includes the 16px padding on each side via
|
||||
* box-sizing:border-box; we subtract both so the wrap exactly
|
||||
* fills the content box without spilling into padding. */
|
||||
var w = (container.clientWidth || window.innerWidth) - 32;
|
||||
return w > 0 ? w : 600;
|
||||
}
|
||||
|
||||
/* Per-slide scale: divides each slides actual rendered native
|
||||
* width into the panel width, so we always fill the panel. No
|
||||
* upscale cap — pptx-preview always rasterizes against the init
|
||||
* canvas (960×540 here), so text/charts inside the slide are
|
||||
* vector or canvas-rendered and stay legible when scaled up. */
|
||||
function scaleFor(nativeW) {
|
||||
return availableWidth() / (nativeW || SLIDE_W);
|
||||
}
|
||||
|
||||
/* Wrap each rendered slide and apply the scale. Called ONCE,
|
||||
|
|
@ -1172,19 +1183,23 @@ html, body { margin: 0; padding: 0; background: var(--bg); color: var(--fg); fon
|
|||
* move slides out from under the librarys references and break
|
||||
* its internal state. */
|
||||
function wrapSlides() {
|
||||
var scale = computeScale();
|
||||
var children = Array.prototype.slice.call(container.children);
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
var slide = children[i];
|
||||
if (!slide.classList || slide.classList.contains('lc-slide-wrap') || slide.classList.contains('lc-pptx-loading')) {
|
||||
continue;
|
||||
}
|
||||
/* Cache the slides actual rendered size BEFORE applying any
|
||||
* transform — measurements after a CSS scale no longer reflect
|
||||
* native pixels and would feed back into wrong sizing on
|
||||
* resize. */
|
||||
var nativeW = slide.offsetWidth || SLIDE_W;
|
||||
var nativeH = slide.offsetHeight || SLIDE_H;
|
||||
if (slide.dataset) {
|
||||
slide.dataset.lcNativeW = String(nativeW);
|
||||
slide.dataset.lcNativeH = String(nativeH);
|
||||
}
|
||||
var scale = scaleFor(nativeW);
|
||||
var wrap = document.createElement('div');
|
||||
wrap.className = 'lc-slide-wrap';
|
||||
wrap.style.width = (nativeW * scale) + 'px';
|
||||
|
|
@ -1200,7 +1215,6 @@ html, body { margin: 0; padding: 0; background: var(--bg); color: var(--fg); fon
|
|||
* resize). Reads the cached native dimensions from the slides
|
||||
* dataset so we never re-measure an already-scaled box. */
|
||||
function refit() {
|
||||
var scale = computeScale();
|
||||
var wraps = container.querySelectorAll('.lc-slide-wrap');
|
||||
for (var i = 0; i < wraps.length; i++) {
|
||||
var wrap = wraps[i];
|
||||
|
|
@ -1208,6 +1222,7 @@ html, body { margin: 0; padding: 0; background: var(--bg); color: var(--fg); fon
|
|||
if (!inner || !inner.dataset) { continue; }
|
||||
var nativeW = parseFloat(inner.dataset.lcNativeW) || SLIDE_W;
|
||||
var nativeH = parseFloat(inner.dataset.lcNativeH) || SLIDE_H;
|
||||
var scale = scaleFor(nativeW);
|
||||
wrap.style.width = (nativeW * scale) + 'px';
|
||||
wrap.style.height = (nativeH * scale) + 'px';
|
||||
inner.style.transform = 'scale(' + scale + ')';
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue