1/** 2 * Anti-Flicker Script for Unified Workflow System 3 * 4 * This script should be injected directly into the <head> section 5 * BEFORE any other content to prevent Flash of Original Content (FOOC) 6 * 7 * Usage: Add this script tag immediately after the opening <head> tag 8 */ 9 10(function() { 11 'use strict'; 12 13 // Configuration - can be overridden by window.unifiedWorkflowConfig 14 const defaultConfig = { 15 maxHideTime: 5000, // Maximum time to hide content (5 seconds) 16 showLoadingIndicator: true, // Show loading spinner 17 debug: false, // Enable debug logging 18 hideMethod: 'opacity' // 'opacity' or 'visibility' 19 }; 20 21 // Get configuration from window or use defaults 22 const config = Object.assign({}, defaultConfig, window.unifiedWorkflowConfig || {}); 23 24 // Debug logging function 25 function log(message, level = 'info') { 26 if (config.debug) { 27 const timestamp = new Date().toLocaleTimeString(); 28 console.log(`[${timestamp}] ð¯ Anti-Flicker: ${message}`); 29 } 30 } 31 32 // State tracking 33 let contentHidden = false; 34 let loadingIndicatorShown = false; 35 let safetyTimeoutId = null; 36 37 // Hide content immediately 38 function hideContent() { 39 if (contentHidden) return; 40 41 log('ð Hiding content to prevent flicker'); 42 43 // Add CSS to hide content 44 const style = document.createElement('style'); 45 style.id = 'unified-workflow-anti-flicker'; 46 style.textContent = ` 47 body { 48 ${config.hideMethod === 'opacity' ? 'opacity: 0 !important;' : 'visibility: hidden !important;'} 49 transition: opacity 0.3s ease !important; 50 } 51 52 /* Loading indicator styles */ 53 #unified-workflow-loading { 54 position: fixed !important; 55 top: 50% !important; 56 left: 50% !important; 57 transform: translate(-50%, -50%) !important; 58 z-index: 999999 !important; 59 background: rgba(255, 255, 255, 0.95) !important; 60 border-radius: 12px !important; 61 padding: 20px 30px !important; 62 box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15) !important; 63 display: flex !important; 64 align-items: center !important; 65 gap: 15px !important; 66 font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif !important; 67 font-size: 14px !important; 68 color: #333 !important; 69 opacity: 1 !important; 70 visibility: visible !important; 71 } 72 73 .unified-workflow-spinner { 74 width: 20px !important; 75 height: 20px !important; 76 border: 2px solid #e3e3e3 !important; 77 border-top: 2px solid #007bff !important; 78 border-radius: 50% !important; 79 animation: unified-workflow-spin 1s linear infinite !important; 80 } 81 82 @keyframes unified-workflow-spin { 83 0% { transform: rotate(0deg); } 84 100% { transform: rotate(360deg); } 85 } 86 `; 87 88 document.head.appendChild(style); 89 contentHidden = true; 90 91 // Show loading indicator if enabled 92 if (config.showLoadingIndicator) { 93 showLoadingIndicator(); 94 } 95 96 // Safety timeout to show content even if workflow system fails 97 safetyTimeoutId = setTimeout(() => { 98 log('â° Safety timeout reached - showing content automatically', 'warning'); 99 showContent(); 100 }, config.maxHideTime); 101 } 102 103 // Show loading indicator 104 function showLoadingIndicator() { 105 if (loadingIndicatorShown) return; 106 107 // Wait for body to be available 108 const showIndicator = () => { 109 if (!document.body) { 110 setTimeout(showIndicator, 10); 111 return; 112 } 113 114 const indicator = document.createElement('div'); 115 indicator.id = 'unified-workflow-loading'; 116 indicator.innerHTML = ` 117 <div class="unified-workflow-spinner"></div> 118 <span>Personalizing content...</span> 119 `; 120 121 document.body.appendChild(indicator); 122 loadingIndicatorShown = true; 123 log('ð Loading indicator shown'); 124 }; 125 126 showIndicator(); 127 } 128 129 // Hide loading indicator 130 function hideLoadingIndicator() { 131 const indicator = document.getElementById('unified-workflow-loading'); 132 if (indicator) { 133 indicator.remove(); 134 loadingIndicatorShown = false;
135 log('ð Loading indicator hidden'); 136 } 137 } 138 139 // Show content 140 function showContent() { 141 if (!contentHidden) return; 142 143 log('ð Revealing content'); 144 145 // Clear safety timeout 146 if (safetyTimeoutId) { 147 clearTimeout(safetyTimeoutId); 148 safetyTimeoutId = null; 149 } 150 151 // Hide loading indicator 152 hideLoadingIndicator(); 153 154 // Remove anti-flicker styles 155 const style = document.getElementById('unified-workflow-anti-flicker'); 156 if (style) { 157 style.remove(); 158 } 159 160 contentHidden = false; 161 } 162 163 // Expose global functions for the main workflow system to use 164 window.unifiedWorkflowAntiFlicker = { 165 hideContent, 166 showContent, 167 hideLoadingIndicator, 168 showLoadingIndicator, 169 isContentHidden: () => contentHidden, 170 isLoadingIndicatorShown: () => loadingIndicatorShown 171 }; 172 173 // Auto-hide content immediately if not already hidden 174 if (document.readyState === 'loading') { 175 // Document is still loading, hide immediately 176 hideContent(); 177 } else { 178 // Document already loaded, check if we should still hide 179 if (!window.workflowSystem || !window.workflowSystem.initialized) { 180 hideContent(); 181 } 182 } 183 184 log('â Anti-flicker script initialized'); 185 186})();
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.