1// Custom HTML widget renderer for superblog 2// Decodes base64-encoded HTML content and renders it in place 3(function () { 4 'use strict'; 5 6 if (window.__customHtmlRendererInit) return; 7 window.__customHtmlRendererInit = true; 8 9 function decodeBase64(str) { 10 try { 11 return decodeURIComponent( 12 atob(str) 13 .split('') 14 .map(function (c) { 15 return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); 16 }) 17 .join('') 18 ); 19 } catch (e) { 20 // Fallback for simple ASCII 21 try { 22 return atob(str); 23 } catch (e2) { 24 console.error('Failed to decode base64:', e2); 25 return ''; 26 } 27 } 28 } 29 30 function processCustomHtmlWidgets() { 31 const widgets = document.querySelectorAll( 32 'div[data-type="customHTML"][data-html-content]' 33 ); 34 35 widgets.forEach((widget) => { 36 // Skip if already processed 37 if (widget.dataset.rendered === 'true') return; 38 widget.dataset.rendered = 'true'; 39 40 const encodedContent = widget.getAttribute('data-html-content'); 41 const size = widget.getAttribute('data-size') || 'full'; 42 43 if (!encodedContent) return; 44 45 const htmlContent = decodeBase64(encodedContent); 46 47 if (!htmlContent) return; 48 49 // Create a container for the rendered content 50 const container = document.createElement('div'); 51 container.className = `velocity-html-rendered velocity-html-${size}`; 52 container.innerHTML = htmlContent; 53 54 // Replace the widget with the rendered content 55 widget.parentNode.replaceChild(container, widget); 56 57 // Execute any scripts in the HTML 58 const scripts = container.querySelectorAll('script'); 59 scripts.forEach((script) => { 60 const newScript = document.createElement('script'); 61 if (script.src) { 62 newScript.src = script.src; 63 } else { 64 newScript.textContent = script.textContent; 65 } 66 document.head.appendChild(newScript); 67 // Clean up after execution 68 setTimeout(() => { 69 if (newScript.parentNode) { 70 newScript.parentNode.removeChild(newScript); 71 } 72 }, 100); 73 }); 74 }); 75 } 76 77 function init() { 78 // Small delay to ensure DOM is ready 79 setTimeout(processCustomHtmlWidgets, 100); 80 } 81 82 // Run on initial load 83 if (document.readyState === 'loading') { 84 document.addEventListener('DOMContentLoaded', init); 85 } else { 86 init(); 87 } 88 89 // Re-run on Turbo navigation 90 document.addEventListener('turbo:load', init); 91})();
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.