@@ -13,6 +13,7 @@ export function getWebviewContent(
1313<head>
1414 <meta charset="UTF-8">
1515 <meta name="viewport" content="width=device-width, initial-scale=1">
16+ <meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src 'unsafe-inline' https://cdn.jsdelivr.net; script-src 'unsafe-inline' https://cdn.jsdelivr.net https://cdnjs.cloudflare.com;">
1617 <title>PostScript Preview</title>
1718 <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@simonwep/pickr/dist/themes/nano.min.css" />
1819 <script src="https://cdn.jsdelivr.net/npm/@simonwep/pickr/dist/pickr.min.js"></script>
@@ -22,6 +23,7 @@ export function getWebviewContent(
2223 pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.worker.min.js';
2324 </script>
2425 <style>
26+ /* ... existing styles ... */
2527 :root {
2628 --accent: #209a8e;
2729 --accent-hover: #1a7d73;
@@ -103,7 +105,6 @@ export function getWebviewContent(
103105 display: flex;
104106 justify-content: center;
105107 align-items: center;
106- /* Ensure the container is positioned for absolute children if needed */
107108 }
108109
109110 #svgContainer {
@@ -119,14 +120,12 @@ export function getWebviewContent(
119120 max-width: 100%;
120121 max-height: 100%;
121122 box-shadow: 0 0 20px rgba(0,0,0,0.2);
122- /* Background applied dynamically */
123123 }
124124
125125 .pickr-wrap {
126126 margin-left: 8px;
127127 }
128128
129- /* Pickr overrides */
130129 .pickr .pcr-button {
131130 width: 20px !important;
132131 height: 20px !important;
@@ -181,38 +180,53 @@ export function getWebviewContent(
181180
182181 function renderPage(num) {
183182 pdfDoc.getPage(num).then(function(page) {
184- const viewport = page.getViewport({scale: 1.0}); // scale 1.0 for SVG is fine, it means 72DPI usually
183+ const viewport = page.getViewport({scale: 1.0});
185184
186185 page.getOperatorList().then(function (opList) {
187186 const svgGfx = new pdfjsLib.SVGGraphics(page.commonObjs, page.objs);
188187
189188 svgGfx.getSVG(opList, viewport).then(function (svg) {
190189 svgContainer.innerHTML = '';
191190
192- // Fix Aspect Ratio & Sizing
193- // 1. Ensure viewBox exists (pdf.js usually sets it)
191+ // 1. Aspect Ratio Safety
192+ svg.setAttribute('preserveAspectRatio', 'xMidYMid meet');
193+
194194 if (!svg.getAttribute('viewBox')) {
195195 svg.setAttribute('viewBox', \`0 0 \${viewport.width} \${viewport.height}\`);
196196 }
197- // 2. Remove fixed pixel dimensions if present to prevent squashing when forcing 100%
197+
198+ // 2. Paper Background Strategy: Inject a Rect
199+ const bgRect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
200+ bgRect.setAttribute("x", "0");
201+ bgRect.setAttribute("y", "0");
202+ bgRect.setAttribute("width", viewport.width);
203+ bgRect.setAttribute("height", viewport.height);
204+ bgRect.setAttribute("fill", "white"); // Default Paper Color
205+ bgRect.setAttribute("id", "paper-bg");
206+
207+ svg.insertBefore(bgRect, svg.firstChild);
208+
209+ // 3. Sizing
198210 svg.removeAttribute('width');
199211 svg.removeAttribute('height');
200-
201- // 3. Set style for responsiveness BEFORE pan-zoom initialization
202- // svg-pan-zoom needs the element to have some size or container to have size
212+
203213 svg.style.width = '100%';
204214 svg.style.height = '100%';
205215 svg.style.display = 'block';
216+ svg.style.backgroundColor = 'transparent';
217+
218+ // 4. Color Picker Restore
219+ if (pcr) {
220+ bgRect.setAttribute("fill", pcr.getColor().toHEXA().toString());
221+ }
206222
207- // 4. Check color picker state
208- const savedColor = pcr ? pcr.getColor().toHEXA().toString() : '#FFFFFF';
209- svg.style.backgroundColor = savedColor;
210-
211223 svgContainer.appendChild(svg);
212224
213- // Initialize Pan Zoom
214- // Use a small timeout to let the DOM settle?
215- setTimeout(() => initPanZoom(svg), 0);
225+ // 5. Initialize Pan Zoom safely
226+ // Use requestAnimationFrame to let the DOM update dimensions first
227+ window.requestAnimationFrame(() => {
228+ initPanZoom(svg);
229+ });
216230 });
217231 });
218232 });
@@ -223,23 +237,31 @@ export function getWebviewContent(
223237 }
224238
225239 function initPanZoom(svgElement) {
240+ if (typeof svgPanZoom === 'undefined') {
241+ console.error("svg-pan-zoom library not loaded!");
242+ return;
243+ }
244+
226245 if (panZoomInstance) {
227246 panZoomInstance.destroy();
228247 panZoomInstance = null;
229248 }
230249
231250 if (!svgElement.id) svgElement.id = 'preview-svg';
232251
233- // svg-pan-zoom options
234- panZoomInstance = svgPanZoom(svgElement, {
235- zoomEnabled: true,
236- controlIconsEnabled: false,
237- fit: true,
238- center: true,
239- minZoom: 0.1,
240- maxZoom: 10,
241- contain: true // This helps fitting without squashing
242- });
252+ try {
253+ panZoomInstance = svgPanZoom(svgElement, {
254+ zoomEnabled: true,
255+ controlIconsEnabled: false,
256+ fit: true,
257+ center: true,
258+ minZoom: 0.1,
259+ maxZoom: 10,
260+ contain: true
261+ });
262+ } catch (e) {
263+ console.error("PanZoom Initialization Failed:", e);
264+ }
243265 }
244266
245267 // --- Controls ---
@@ -259,7 +281,6 @@ export function getWebviewContent(
259281 });
260282
261283 document.getElementById('zoomIn').addEventListener('click', () => {
262- // Check if instance exists, if not try to re-init (shouldn't happen)
263284 if (panZoomInstance) panZoomInstance.zoomIn();
264285 });
265286
@@ -275,21 +296,19 @@ export function getWebviewContent(
275296 });
276297
277298 // --- Coloring ---
278- // Defaults to White
279299
280300 pcr = Pickr.create({
281301 el: '#colorPicker',
282302 theme: 'nano',
283- default: '#FFFFFF',
303+ default: '#FFFFFF', // Paper Default
284304 swatches: ['#FFFFFF', '#000000', '#1EBFAF', '#525659', '#333333'],
285305 components: { preview: true, opacity: false, hue: true, interaction: { input: true, save: true } }
286306 }).on('save', (color) => {
287307 const hex = color.toHEXA().toString();
288- // Apply to active SVG
289- const svg = document.querySelector('svg');
290- if (svg) {
291- // svg-pan-zoom might warp things, but background on the SVG tag usually persists
292- svg.style.backgroundColor = hex;
308+ // Apply to the paper-bg rect
309+ const bgRect = document.getElementById('paper-bg');
310+ if (bgRect) {
311+ bgRect.setAttribute('fill', hex);
293312 }
294313 pcr.hide();
295314 });
0 commit comments