diff --git a/CHANGELOG.md b/CHANGELOG.md index d824959..7db7930 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,11 @@ Follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) · versioned wi ## [Unreleased] +## [1.42.1] — 2026-09-22 + +### Fixed +- **Magazine import preview: the page sat at the bottom of its pane.** The page image (and the region boxes drawn over it) is now aligned to the top of the preview, so it stays in view next to a long recognised-text column. + ## [1.42.0] — 2026-09-22 ### Added diff --git a/VERSION b/VERSION index 1933dfa..e640847 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.42.0 \ No newline at end of file +1.42.1 diff --git a/static/index.html b/static/index.html index daf6c4d..226a5ea 100644 --- a/static/index.html +++ b/static/index.html @@ -27,12 +27,12 @@ - - - - - - + + + + + + diff --git a/static/js/magazine.js b/static/js/magazine.js index 6b565af..d5bd50f 100644 --- a/static/js/magazine.js +++ b/static/js/magazine.js @@ -471,14 +471,15 @@ const MAG_PREVIEW_TYPES = { let _magPreviewSeen = { page: null, keys: new Set() }; // Fit the box layer to the part of the frame the page image actually covers ("contain" scaling -// leaves bars around it), so a box drawn at 50% sits at 50% of the page, not of the frame. +// leaves bars beside or below it -- the page is top-aligned), so a box drawn at 50% sits at 50% of +// the page, not of the frame. function magFitPreviewLayer() { const img = $('mag-ingest-preview-img'), layer = $('mag-ingest-preview-boxes'); if (!img || !layer || !img.naturalWidth || !img.clientWidth) return; const scale = Math.min(img.clientWidth / img.naturalWidth, img.clientHeight / img.naturalHeight); const w = img.naturalWidth * scale, h = img.naturalHeight * scale; layer.style.left = (img.offsetLeft + (img.clientWidth - w) / 2) + 'px'; - layer.style.top = (img.offsetTop + (img.clientHeight - h) / 2) + 'px'; + layer.style.top = img.offsetTop + 'px'; // the page is drawn at the top of its frame (object-position: top) layer.style.width = w + 'px'; layer.style.height = h + 'px'; } diff --git a/static/style.css b/static/style.css index 4defeb5..42c4784 100644 --- a/static/style.css +++ b/static/style.css @@ -5192,7 +5192,8 @@ input[list="lang-codes"] { /* Live region boxes on the page being read (magazine ingestion preview) */ .mag-ingest-preview-canvas { position: relative; flex: 1 1 auto; min-height: 0; display: flex; } -.mag-ingest-preview-canvas img { width: 100%; height: 100%; object-fit: contain; } +.mag-ingest-preview-canvas { align-items: flex-start; } +.mag-ingest-preview-canvas img { width: 100%; height: 100%; object-fit: contain; object-position: center top; } .mag-ingest-preview-boxes { position: absolute; pointer-events: none; } .mag-preview-box { position: absolute; border: 2px solid var(--c, #3b82f6); border-radius: 2px; background: color-mix(in srgb, var(--c, #3b82f6) 14%, transparent); } diff --git a/tests/magazine.spec.js b/tests/magazine.spec.js index e38d6e9..e800876 100644 --- a/tests/magazine.spec.js +++ b/tests/magazine.spec.js @@ -656,7 +656,7 @@ test('the live preview draws the page regions over the page image as they arrive preview.style.width = '800px'; const canvas = document.createElement('canvas'); canvas.width = 100; canvas.height = 200; const img = document.getElementById('mag-ingest-preview-img'); - img.style.height = '400px'; + img.style.height = '1400px'; await new Promise(r => { img.onload = r; img.src = canvas.toDataURL('image/png'); }); }); await page.evaluate(() => window.magRenderPreviewBoxes(5, [ @@ -669,9 +669,10 @@ test('the live preview draws the page regions over the page image as they arrive await expect(page.locator('#mag-ingest-preview-legend')).toContainText('2 regions'); const [imgBox, layerBox] = await Promise.all([ page.locator('#mag-ingest-preview-img').boundingBox(), page.locator('#mag-ingest-preview-boxes').boundingBox()]); - // The layer has the page's 1:2 shape and is centred in the wider frame. + // The layer has the page's 1:2 shape, is centred across the wider frame and sits at its top. expect(Math.abs(layerBox.height - 2 * layerBox.width)).toBeLessThan(2); expect(Math.abs((layerBox.x + layerBox.width / 2) - (imgBox.x + imgBox.width / 2))).toBeLessThan(2); + expect(Math.abs(layerBox.y - imgBox.y)).toBeLessThan(2); // A region that appears on the next poll is marked new; the ones already shown are not. await page.evaluate(() => window.magRenderPreviewBoxes(5, [ { x: 0, y: 0, w: 100, h: 10, type: 'title', n: 1 },