1(function() { 2 if (window.__PRODUCTOS_SCREENSHOT_INIT) return; 3 window.__PRODUCTOS_SCREENSHOT_INIT = true; 4 5 // Pinned version so a sandbox restored from a snapshot always loads the 6 // same engine. Update deliberately, not by floating @latest. 7 var SNAPDOM_URL = "https://cdn.jsdelivr.net/npm/@zumer/snapdom/dist/snapdom.js"; 8 var loaderPromise = null; 9 10 function loadSnapdom() { 11 if (window.snapdom) return Promise.resolve(window.snapdom); 12 if (loaderPromise) return loaderPromise; 13 loaderPromise = new Promise(function(resolve, reject) { 14 var s = document.createElement("script"); 15 s.src = SNAPDOM_URL; 16 s.crossOrigin = "anonymous"; 17 s.onload = function() { 18 if (window.snapdom) resolve(window.snapdom); 19 else reject(new Error("snapdom loaded but global is missing")); 20 }; 21 s.onerror = function() { 22 loaderPromise = null; 23 reject(new Error("Failed to load snapdom (CDN unreachable or blocked by CSP)")); 24 }; 25 document.head.appendChild(s); 26 }); 27 return loaderPromise; 28 } 29 30 function reply(source, payload) { 31 var target = source || window.parent; 32 try { target.postMessage(payload, "*"); } 33 catch (_) { try { window.parent.postMessage(payload, "*"); } catch (__) {} } 34 } 35 36 function shouldSkipForCapture(el) { 37 if (!el) return false; 38 var id = el.id; 39 if (id === "productos-inspector-overlay") return true; 40 if (id === "productos-inspector-highlights") return true; 41 if (el.getAttribute && el.getAttribute("data-productos-skip-shot") === "1") return true; 42 return false; 43 } 44 45 // SnapDOM doesn't have an ignoreElements hook, so we hide our injected UI 46 // for the duration of the capture and restore inline display afterwards. 47 function hideInjectedOverlays() { 48 var nodes = document.querySelectorAll( 49 "#productos-inspector-overlay, #productos-inspector-highlights, [data-productos-skip-shot='1']" 50 ); 51 var restorers = []; 52 for (var i = 0; i < nodes.length; i++) { 53 var n = nodes[i]; 54 var prev = n.style.display; 55 restorers.push({ node: n, prev: prev }); 56 n.style.display = "none"; 57 } 58 return function restore() { 59 for (var i = 0; i < restorers.length; i++) { 60 restorers[i].node.style.display = restorers[i].prev; 61 } 62 }; 63 } 64 65 window.addEventListener("message", function(e) { 66 var data = e.data; 67 if (!data || data.type !== "productos-screenshot-request") return; 68 var requestId = (data && data.requestId) || ""; 69 70 var restoreOverlays = null; 71 loadSnapdom().then(function(snapdom) { 72 restoreOverlays = hideInjectedOverlays(); 73 // toCanvas returns a real <canvas> we can call toDataURL on. We pass 74 // documentElement to capture the full viewport-equivalent layout. 75 return snapdom.toCanvas(document.documentElement, { 76 // Snapdom honours device pixel ratio by default; cap it so massive 77 // retina pages don't produce 30MB pngs. 78 scale: 1, 79 // Embed external images / fonts so the canvas isn't tainted. 80 embedFonts: true, 81 }); 82 }).then(function(canvas) { 83 if (restoreOverlays) restoreOverlays(); 84 var dataUrl = canvas.toDataURL("image/png"); 85 reply(e.source, { 86 type: "productos-screenshot-result", 87 requestId: requestId, 88 dataUrl: dataUrl, 89 width: canvas.width, 90 height: canvas.height, 91 }); 92 }).catch(function(err) { 93 if (restoreOverlays) restoreOverlays(); 94 reply(e.source, { 95 type: "productos-screenshot-error", 96 requestId: requestId, 97 error: String((err && err.message) || err || "screenshot failed"), 98 }); 99 }); 100 }); 101 102 // Announce readiness so parents that want to enable/disable the button can. 103 try { 104 window.parent.postMessage({ type: "productos-screenshot-ready" }, "*"); 105 } catch (_) {} 106})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.