PageSourceSearch

https://trackflow-app-production.up.railway.app/api/anti-flicker.js

js trackflow-app-production.up.railway.app collected 2026-10-03 12:14:18 UTC 5,551 bytes, 186 lines download raw bytes

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.