1// Tweet widget renderer for superblog 2// Decodes base64-encoded HTML content and renders tweets in place 3(function () { 4 'use strict'; 5 6 if (window.__tweetRendererInit) return; 7 window.__tweetRendererInit = true; 8 9 function decodeBase64(str) { 10 try { 11 return decodeURIComponent(atob(str)); 12 } catch (e) { 13 // Fallback for simple ASCII 14 try { 15 return atob(str); 16 } catch (e2) { 17 console.error('Failed to decode base64:', e2); 18 return ''; 19 } 20 } 21 } 22 23 // Queue of containers waiting for Twitter widgets to load 24 var pendingContainers = []; 25 var twitterScriptLoading = false; 26 27 function loadTwitterWidgets(container) { 28 // If Twitter is ready, load immediately 29 if (window.twttr && window.twttr.widgets) { 30 window.twttr.widgets.load(container); 31 return; 32 } 33 34 // Add to pending queue 35 pendingContainers.push(container); 36 37 // If we're already loading the script, just wait 38 if (twitterScriptLoading) return; 39 40 // Check if script tag exists 41 var existingScript = document.querySelector('script[src*="platform.twitter.com/widgets.js"]'); 42 43 if (!existingScript) { 44 twitterScriptLoading = true; 45 var script = document.createElement('script'); 46 script.src = 'https://platform.twitter.com/widgets.js'; 47 script.async = true; 48 script.charset = 'utf-8'; 49 document.head.appendChild(script); 50 } 51 52 // Poll for twttr to be ready 53 var checkTwitter = function() { 54 if (window.twttr && window.twttr.widgets) { 55 // Process all pending containers 56 while (pendingContainers.length > 0) { 57 var c = pendingContainers.shift(); 58 window.twttr.widgets.load(c); 59 } 60 twitterScriptLoading = false; 61 } else { 62 setTimeout(checkTwitter, 200); 63 } 64 }; 65 checkTwitter(); 66 } 67 68 function processTweetWidgets() { 69 var widgets = document.querySelectorAll('div.velocity-tweet[data-html]'); 70 71 widgets.forEach(function(widget) { 72 // Skip if already processed 73 if (widget.dataset.rendered === 'true') return; 74 widget.dataset.rendered = 'true'; 75 76 var encodedHtml = widget.getAttribute('data-html'); 77 78 if (!encodedHtml) return; 79 80 var htmlContent = decodeBase64(encodedHtml); 81 82 if (!htmlContent) return; 83 84 // Insert the decoded HTML content 85 widget.innerHTML = htmlContent; 86 87 // Execute any scripts in the HTML (Twitter oEmbed includes a script tag) 88 var scripts = widget.querySelectorAll('script'); 89 scripts.forEach(function(script) { 90 var newScript = document.createElement('script'); 91 if (script.src) { 92 newScript.src = script.src; 93 newScript.async = true; 94 newScript.charset = 'utf-8'; 95 } else { 96 newScript.textContent = script.textContent; 97 } 98 document.head.appendChild(newScript); 99 // Remove original script from widget to avoid confusion 100 script.remove(); 101 }); 102 103 // Also manually trigger widget loading as a fallback 104 requestAnimationFrame(function() { 105 loadTwitterWidgets(widget); 106 }); 107 }); 108 } 109 110 function init() { 111 // Small delay to ensure DOM is ready 112 setTimeout(processTweetWidgets, 150); 113 } 114 115 // Run on initial load 116 if (document.readyState === 'loading') { 117 document.addEventListener('DOMContentLoaded', init); 118 } else { 119 init(); 120 } 121 122 // Re-run on Turbo navigation 123 document.addEventListener('turbo:load', init); 124})();
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.