Auto Refresh Interface for Hotsauce

Auto refresh for HotSOS. Has improved UI and features with error suppression

// ==UserScript==
// @name         Auto Refresh Interface for Hotsauce
// @namespace    http://tampermonkey.net/
// @version      2.5.1
// @description  Auto refresh for HotSOS. Has improved UI and features with error suppression
// @match        https://na4.m-tech.com/service-optimization/operations/service-orders/PendingOrders
// @grant        none
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    // Global variables
    let refreshInterval;
    let currentIntervalValue;
    let isEnabled = true; // Auto-refresh is enabled by default
    let statusText;
    let toggleCircle;
    let toggleContainer = null;
    let toggle;
    let intervalInput;
    let lastRefreshAttempt = 0;
    let isDragging = false;
    let xOffset = 0;
    let yOffset = 0;
    let initialX, initialY;
    let isUIOperation = false; // Flag to prevent unwanted updates
    const MIN_REFRESH_INTERVAL = 1000; // 1 second minimum between refreshes

    // Settings management
    const Settings = {
        load() {
            const defaultSettings = {
                interval: 30,
                position: { x: 0, y: 0 },
                lastUsedPreset: '30s',
                isEnabled: true // Added isEnabled to default settings
            };
            try {
                return { ...defaultSettings, ...JSON.parse(localStorage.getItem('autoRefreshSettings') || '{}') };
            } catch (e) {
                console.log('Error loading settings, using defaults');
                return defaultSettings;
            }
        },
        save(settings) {
            localStorage.setItem('autoRefreshSettings', JSON.stringify(settings));
        }
    };

    // Preset configurations
    const PRESETS = [
        { label: '15s', value: 15 },
        { label: '30s', value: 30 },
        { label: '1m', value: 60 },
        { label: '5m', value: 300 }
    ];

    // Enhanced page ready check
    function checkPageReady() {
        const refreshButton = findRefreshButton();
        const isLoading = document.querySelector('.loading-screen, .spinner, .mat-progress-spinner');

        if (isLoading) {
            console.log('Loading screen detected, waiting...');
            setTimeout(() => findAndClickRefreshButton(), 500);
            return false;
        }

        return refreshButton !== null;
    }

    function findRefreshButton() {
        try {
            const selectors = [
                'button.mat-icon-button.mat-accent:has(soe-icon[icon="refresh-dot"])',
                'button.mat-icon-button.mat-accent:has(soe-icon[icon="refresh"])',
                'button.mat-icon-button:has(soe-icon[icon="refresh"])',
                'button.mat-icon-button:has(soe-icon[icon="refresh-dot"])',
                'button[soe-data-cy="refresh"]'
            ];

            for (const selector of selectors) {
                try {
                    const button = document.querySelector(selector);
                    if (button) return button;
                } catch (e) {
                    // Silently continue to next selector
                }
            }

            // Fallback to searching for any button with refresh-related attributes
            try {
                const allButtons = document.querySelectorAll('button');
                return Array.from(allButtons).find(button => {
                    try {
                        const buttonText = button.textContent.toLowerCase();
                        const hasRefreshIcon = button.querySelector('soe-icon[icon*="refresh"]');
                        const hasRefreshClass = button.className.toLowerCase().includes('refresh');
                        return hasRefreshIcon || hasRefreshClass || buttonText.includes('refresh');
                    } catch (e) {
                        return false;
                    }
                });
            } catch (e) {
                // Return null if all attempts fail
                return null;
            }
        } catch (e) {
            // Catch and suppress any errors
            console.log('Error in findRefreshButton (suppressed)');
            return null;
        }
    }

    function updateStatus(state = 'normal') {
        if (!statusText || isUIOperation) return; // Skip updating if this is a UI operation

        const now = new Date().toLocaleTimeString();
        const stateColors = {
            success: '#059669',
            error: '#DC2626',
            normal: '#666'
        };

        // Always update with timestamp for any refresh attempt
        statusText.textContent = `Last check: ${now}`;
        statusText.style.color = isEnabled ? stateColors[state] : stateColors.normal;

        if (state === 'error') {
            setTimeout(() => {
                if (isEnabled) updateStatus('normal');
            }, 3000);
        }
    }

    function findAndClickRefreshButton(force = false) {
        const now = Date.now();
        if (!force && now - lastRefreshAttempt < MIN_REFRESH_INTERVAL) {
            console.log('Skipping refresh - too soon since last attempt');
            return false;
        }

        const refreshButton = findRefreshButton();
        if (refreshButton) {
            console.log('Refresh button found and clicked');
            refreshButton.click();
            updateStatus('success'); // Always show success state when refresh button is clicked
            lastRefreshAttempt = now;
            return true;
        }

        if (force) {
            console.log('Forced refresh attempt');
            setTimeout(() => findAndClickRefreshButton(true), 500);
        }

        console.log('Refresh button not found');
        updateStatus('error');
        return false;
    }

    function setupRefreshButtonListener() {
        const refreshButton = findRefreshButton();
        if (refreshButton && !refreshButton.dataset.listenerAdded) {
            refreshButton.addEventListener('click', () => {
                // Set lastRefreshAttempt to ensure we show timestamp instead of guidance
                lastRefreshAttempt = Date.now();

                // Always show success status with timestamp for manual refreshes
                updateStatus('success');

                if (isEnabled && refreshInterval) {
                    clearInterval(refreshInterval);
                    refreshInterval = setInterval(findAndClickRefreshButton, currentIntervalValue * 1000);
                }
            });
            refreshButton.dataset.listenerAdded = 'true';
        }
    }

    function updateInterval(newInterval, intervalInput) {
        if (refreshInterval) {
            clearInterval(refreshInterval);
            refreshInterval = null;
        }

        intervalInput.value = newInterval.toString();
        currentIntervalValue = newInterval;

        if (isEnabled) {
            findAndClickRefreshButton();
            refreshInterval = setInterval(findAndClickRefreshButton, newInterval * 1000);
            console.log('Interval updated to', newInterval, 'seconds');
        }

        const settings = Settings.load();
        settings.interval = newInterval;
        Settings.save(settings);
    }

    function updatePresetButtonStyles(presetContainer, currentValue) {
        const numericValue = parseInt(currentValue);
        presetContainer.querySelectorAll('button').forEach(button => {
            const preset = PRESETS.find(p => p.label === button.textContent);
            const isMatch = preset && preset.value === numericValue;
            button.style.background = isMatch ? '#0066cc' : '#f0f0f0';
            button.style.color = isMatch ? 'white' : '#333';
            button.style.opacity = isEnabled ? '1' : '0.7';
        });
    }

    function handleIntervalUpdate(newInterval, intervalInput, presetContainer) {
        isEnabled = true;
        toggle.style.backgroundColor = '#0066cc';
        toggleCircle.style.transform = 'translateX(14px)';
        updateInterval(newInterval, intervalInput);
        updatePresetButtonStyles(presetContainer, newInterval);
        updateInputStyle(true);

        // Save enabled state
        const settings = Settings.load();
        settings.isEnabled = true;
        Settings.save(settings);
    }

    function updateInputStyle(enabled) {
        if (!intervalInput) return;
        intervalInput.style.opacity = enabled ? '1' : '0.7';
        intervalInput.style.color = enabled ? '#000' : '#666';
    }

    // Simple function to ensure the container is always in view
    function checkContainerVisibility() {
        if (!toggleContainer || isDragging) return;

        const rect = toggleContainer.getBoundingClientRect();
        const viewportWidth = window.innerWidth;
        const viewportHeight = window.innerHeight;

        // Check if container is completely out of view
        if (rect.left > viewportWidth || rect.right < 0 || rect.top > viewportHeight || rect.bottom < 0) {
            console.log('Container off screen, resetting position');
            xOffset = 20;
            yOffset = 20;
            toggleContainer.style.transform = `translate(${xOffset}px, ${yOffset}px)`;

            // Save the new position
            const settings = Settings.load();
            settings.position = { x: xOffset, y: yOffset };
            Settings.save(settings);
        }
    }

    function updateRefreshButtonStatus() {
        // Only update initial status if no refresh has happened yet
        if (lastRefreshAttempt > 0) return;

        const refreshButton = findRefreshButton();
        if (refreshButton) {
            statusText.textContent = "Ready to refresh";
            statusText.style.color = "#059669"; // Success green
        } else {
            statusText.textContent = "Navigate to pending orders page";
            statusText.style.color = "#DC2626"; // Error red
        }
    }

    function createUI() {
        // Load settings
        const settings = Settings.load();
        currentIntervalValue = settings.interval;

        // Load saved enabled state
        isEnabled = settings.hasOwnProperty('isEnabled') ? settings.isEnabled : true;

        // Load saved position
        if (settings.position) {
            xOffset = settings.position.x;
            yOffset = settings.position.y;
        }

        // Create main container
        toggleContainer = document.createElement('div');
        toggleContainer.style.cssText = `
            position: fixed;
            top: 140px;
            right: 100px;
            z-index: 10000;
            background: white;
            padding: 10px 14px;
            border-radius: 8px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
            font-family: system-ui, -apple-system, sans-serif;
            font-size: 11px;
            min-width: 150px;
            width: 180px;
            touch-action: none;
        `;

        // Add a global style to remove focus outlines for all elements in our container
        const style = document.createElement('style');
        style.textContent = `
            #auto-refresh-container button:focus,
            #auto-refresh-container input:focus,
            #auto-refresh-container div:focus {
                outline: none !important;
            }
        `;
        document.head.appendChild(style);

        // Add an ID for our style targeting
        toggleContainer.id = 'auto-refresh-container';

        // Apply saved transform immediately
        toggleContainer.style.transform = `translate(${xOffset}px, ${yOffset}px)`;

        // Create header
        const headerDiv = document.createElement('div');
        headerDiv.style.cssText = `
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 8px;
            padding-bottom: 4px;
            border-bottom: 1px solid #eee;
            cursor: move;
            touch-action: none;
        `;

        const titleSpan = document.createElement('span');
        titleSpan.textContent = 'Auto Refresh';
        titleSpan.style.cssText = 'font-weight: bold; cursor: move;';

        const minimizeButton = document.createElement('button');
        minimizeButton.innerHTML = '−';
        minimizeButton.style.cssText = `
            background: none;
            border: none;
            cursor: pointer;
            padding: 4px 8px;
            color: #666;
            font-size: 14px;
            touch-action: manipulation;
            outline: none; /* Remove focus outline */
        `;

        // Create content container
        const contentDiv = document.createElement('div');
        contentDiv.style.cssText = 'display: flex; flex-direction: column; gap: 8px;';

        // Create preset buttons
        const presetContainer = document.createElement('div');
        presetContainer.style.cssText = 'display: flex; gap: 4px; margin-bottom: 6px;';

        PRESETS.forEach(preset => {
            const button = document.createElement('button');
            button.textContent = preset.label;
            button.style.cssText = `
                padding: 4px 8px;
                background: #f0f0f0;
                color: #333;
                border: none;
                border-radius: 3px;
                font-size: 10px;
                cursor: pointer;
                flex: 1;
                touch-action: manipulation;
                opacity: 0.7;
                outline: none; /* Remove focus outline */
            `;
            presetContainer.appendChild(button);

            const handlePresetClick = (e) => {
                e.preventDefault();
                const newInterval = preset.value;
                handleIntervalUpdate(newInterval, intervalInput, presetContainer);

                // Update settings
                const currentSettings = Settings.load();
                currentSettings.interval = newInterval;
                currentSettings.lastUsedPreset = preset.label;
                currentSettings.isEnabled = true; // Ensure enabled state is saved
                Settings.save(currentSettings);
            };

            button.addEventListener('click', handlePresetClick);
            button.addEventListener('touchend', handlePresetClick);
        });

        // Create interval input section
        const intervalContainer = document.createElement('div');
        intervalContainer.style.cssText = 'display: flex; align-items: center; gap: 8px;';

        const intervalLabel = document.createElement('label');
        intervalLabel.textContent = 'Interval (sec):';
        intervalLabel.style.cssText = 'font-size: 11px; color: #333;';

        intervalInput = document.createElement('input');
        intervalInput.type = 'number';
        intervalInput.min = '5';
        intervalInput.max = '3600';
        intervalInput.value = settings.interval.toString();
        intervalInput.style.cssText = `
            width: 45px;
            padding: 2px 4px;
            border: 1px solid #ccc;
            border-radius: 3px;
            font-size: 11px;
            touch-action: manipulation;
            opacity: 0.7;
            color: #666;
            outline: none; /* Remove focus outline */
        `;

        // Create button container
        const buttonContainer = document.createElement('div');
        buttonContainer.style.cssText = 'display: flex; gap: 2px; margin-left: 2px;';

        const setIntervalButton = document.createElement('button');
        setIntervalButton.textContent = 'Set';
        setIntervalButton.style.cssText = `
            padding: 4px 8px;
            background: #0066cc;
            color: white;
            border: none;
            border-radius: 3px;
            font-size: 10px;
            cursor: pointer;
            touch-action: manipulation;
            outline: none; /* Remove focus outline */
        `;

        const resetDefaultButton = document.createElement('button');
        resetDefaultButton.textContent = 'Def';
        resetDefaultButton.style.cssText = `
            padding: 4px 8px;
            background: #666;
            color: white;
            border: none;
            border-radius: 3px;
            font-size: 10px;
            cursor: pointer;
            touch-action: manipulation;
            outline: none; /* Remove focus outline */
        `;

        // Create toggle switch
        const toggleSwitch = document.createElement('div');
        toggleSwitch.style.cssText = 'display: flex; align-items: center; gap: 8px;';

        toggle = document.createElement('div');
        toggle.style.cssText = `
            width: 32px;
            height: 18px;
            background: ${isEnabled ? '#0066cc' : '#ccc'};
            border-radius: 9px;
            position: relative;
            transition: background-color 0.2s;
            cursor: pointer;
            touch-action: manipulation;
            outline: none; /* Remove focus outline */
        `;

        toggleCircle = document.createElement('div');
        toggleCircle.style.cssText = `
            width: 14px;
            height: 14px;
            background: white;
            border-radius: 50%;
            position: absolute;
            top: 2px;
            left: 2px;
            transition: transform 0.2s;
            transform: ${isEnabled ? 'translateX(14px)' : 'translateX(0)'};
        `;

        const toggleLabel = document.createElement('span');
        toggleLabel.textContent = 'Enable Auto-refresh';
        toggleLabel.style.cssText = 'color: #333; font-size: 11px;';

        // Create status text with better initial guidance
        statusText = document.createElement('div');
        statusText.style.cssText = 'font-size: 10px; color: #666;';
        statusText.textContent = 'Navigate to pending orders page';

        // Assemble UI
        toggle.appendChild(toggleCircle);
        toggleSwitch.appendChild(toggle);
        toggleSwitch.appendChild(toggleLabel);

        headerDiv.appendChild(titleSpan);
        headerDiv.appendChild(minimizeButton);

        intervalContainer.appendChild(intervalLabel);
        intervalContainer.appendChild(intervalInput);
        buttonContainer.appendChild(setIntervalButton);
        buttonContainer.appendChild(resetDefaultButton);
        intervalContainer.appendChild(buttonContainer);

        contentDiv.appendChild(presetContainer);
        contentDiv.appendChild(intervalContainer);
        contentDiv.appendChild(toggleSwitch);
        contentDiv.appendChild(statusText);

        toggleContainer.appendChild(headerDiv);
        toggleContainer.appendChild(contentDiv);
        document.body.appendChild(toggleContainer);

        // Setup dragging functionality with improved error handling
        function dragStart(e) {
            try {
                if (e.target === minimizeButton) return;

                // Prevent default only when needed to avoid conflicts
                if (e.type === 'touchstart' && e.target.closest('.auto-refresh-container')) {
                    e.preventDefault();
                }

                // Get exact current position for smooth dragging
                const transform = toggleContainer.style.transform;
                const match = transform.match(/translate\((-?\d+)px, *(-?\d+)px\)/);
                if (match) {
                    xOffset = parseInt(match[1]);
                    yOffset = parseInt(match[2]);
                }

                const event = e.type === 'touchstart' ? e.touches[0] : e;
                initialX = event.clientX - xOffset;
                initialY = event.clientY - yOffset;

                if (e.target === headerDiv || e.target === titleSpan || e.target === toggleContainer) {
                    isDragging = true;
                }
            } catch (err) {
                console.log('Error in drag start:', err);
                isDragging = false;
            }
        }

        function drag(e) {
            try {
                if (isDragging) {
                    e.preventDefault();
                    const event = e.type === 'touchmove' ? e.touches[0] : e;
                    xOffset = event.clientX - initialX;
                    yOffset = event.clientY - initialY;
                    toggleContainer.style.transform = `translate(${xOffset}px, ${yOffset}px)`;
                }
            } catch (err) {
                console.log('Error in drag:', err);
                isDragging = false;
            }
        }

        function dragEnd() {
            try {
                if (isDragging) {
                    isDragging = false;

                    // Save position
                    const settings = Settings.load();
                    settings.position = { x: xOffset, y: yOffset };
                    Settings.save(settings);
                }
            } catch (err) {
                console.log('Error in drag end:', err);
                isDragging = false;
            }
        }

        // Add drag events with improved error handling
        toggleContainer.addEventListener('mousedown', dragStart);
        document.addEventListener('mousemove', drag);
        document.addEventListener('mouseup', dragEnd);

        // Special handling for touch events to work better on tablets/touch devices
        toggleContainer.addEventListener('touchstart', dragStart, { passive: false });
        document.addEventListener('touchmove', drag, { passive: false });
        document.addEventListener('touchend', dragEnd, { passive: true });
        document.addEventListener('touchcancel', () => {
            if (isDragging) {
                isDragging = false;
                console.log('Touch cancelled, reset drag state');
            }
        });

        // Minimize/Maximize functionality
        let isMinimized = false;
        minimizeButton.addEventListener('click', (e) => {
            // Prevent status updates during UI operations
            isUIOperation = true;
            e.stopPropagation(); // Prevent event bubbling

            isMinimized = !isMinimized;
            contentDiv.style.display = isMinimized ? 'none' : 'flex';
            minimizeButton.innerHTML = isMinimized ? '+' : '−';
            toggleContainer.style.padding = isMinimized ? '10px 14px 2px' : '10px 14px';

            // Reset flag after operation is complete
            setTimeout(() => {
                isUIOperation = false;
            }, 100);
        });

        // Set interval button handlers
        setIntervalButton.addEventListener('click', (e) => {
            e.preventDefault();
            const newInterval = Math.max(5, Math.min(3600, parseInt(intervalInput.value) || 30));
            handleIntervalUpdate(newInterval, intervalInput, presetContainer);
        });

        resetDefaultButton.addEventListener('click', (e) => {
            e.preventDefault();
            handleIntervalUpdate(30, intervalInput, presetContainer);
        });

        // Toggle switch functionality
        toggle.addEventListener('click', function() {
            isEnabled = !isEnabled;
            if (isEnabled) {
                toggle.style.backgroundColor = '#0066cc';
                toggleCircle.style.transform = 'translateX(14px)';
                const currentValue = parseInt(intervalInput.value) || 30;
                updateInterval(currentValue, intervalInput);
                updatePresetButtonStyles(presetContainer, currentValue);
                updateInputStyle(true);

                // Update status when enabling
                updateRefreshButtonStatus();
            } else {
                toggle.style.backgroundColor = '#ccc';
                toggleCircle.style.transform = 'translateX(0)';
                if (refreshInterval) {
                    clearInterval(refreshInterval);
                    refreshInterval = null;
                }
                statusText.style.color = '#666';
                statusText.textContent = 'Auto-refresh disabled';
                updatePresetButtonStyles(presetContainer, intervalInput.value);
                updateInputStyle(false);
            }

            // Save the enabled state
            const settings = Settings.load();
            settings.isEnabled = isEnabled;
            Settings.save(settings);
        });

        // Set up mutation observer for dynamic refresh button
        const observer = new MutationObserver(() => {
            setupRefreshButtonListener();

            // Only update status text if no refresh has happened yet
            if (!lastRefreshAttempt) {
                updateRefreshButtonStatus();
            }
        });

        observer.observe(document.body, {
            childList: true,
            subtree: true,
            attributes: true,
            attributeFilter: ['class']
        });

        // Initial setup
        setupRefreshButtonListener();
        updateRefreshButtonStatus(); // Check initial status

        // Set initial interval from settings and update presets
        intervalInput.value = settings.interval.toString();
        updatePresetButtonStyles(presetContainer, settings.interval);
        updateInputStyle(isEnabled);
    }

    // Initialization function - create UI immediately without waiting for page to be ready
    function initScript() {
        console.log('Starting initialization...');

        // Create UI immediately
        createUI();

        // Force position check after a short delay
        setTimeout(checkContainerVisibility, 500);

        // Set up observers and listeners
        const observer = new MutationObserver((mutations) => {
            const loadingScreenChange = mutations.some(mutation =>
                Array.from(mutation.addedNodes).some(node =>
                    node.nodeType === 1 && (
                        node.classList?.contains('loading-screen') ||
                        node.classList?.contains('spinner') ||
                        node.classList?.contains('mat-progress-spinner')
                    )
                )
            );

            if (loadingScreenChange) {
                console.log('Loading screen change detected');
                setTimeout(() => findAndClickRefreshButton(true), 500);
            }
        });

        observer.observe(document.body, {
            subtree: true,
            childList: true,
            attributes: true,
            attributeFilter: ['class', 'style']
        });

        // Add event listener for window resize
        window.addEventListener('resize', function() {
            if (!isDragging) {
                checkContainerVisibility();
            }
        });

        // Also check visibility after orientation change
        window.addEventListener('orientationchange', function() {
            setTimeout(function() {
                checkContainerVisibility();
            }, 300);
        });

        // Initialize refresh functionality if page is ready
        if (checkPageReady()) {
            setupRefreshButtonListener();
            console.log('Page ready, refresh functionality initialized');

            // Only show guidance if no refresh has happened yet
            if (lastRefreshAttempt === 0) {
                updateRefreshButtonStatus();
            }

            // Start auto-refresh if enabled by default
            if (isEnabled) {
                if (refreshInterval) clearInterval(refreshInterval);
                refreshInterval = setInterval(findAndClickRefreshButton, currentIntervalValue * 1000);
                // Initial refresh
                setTimeout(() => findAndClickRefreshButton(), 1000);
            }
        } else {
            console.log('Page not ready, will initialize refresh functionality when ready');
            // Update status to indicate page navigation needed
            if (statusText) {
                statusText.textContent = 'Navigate to pending orders page';
                statusText.style.color = '#DC2626'; // Error red
            }

            // Set up periodic check for refresh button
            const readyCheckInterval = setInterval(() => {
                if (checkPageReady()) {
                    setupRefreshButtonListener();
                    console.log('Page now ready, refresh functionality initialized');
                    updateRefreshButtonStatus(); // Update status when page becomes ready

                    // Start auto-refresh if enabled by default
                    if (isEnabled) {
                        if (refreshInterval) clearInterval(refreshInterval);
                        refreshInterval = setInterval(findAndClickRefreshButton, currentIntervalValue * 1000);
                        // Initial refresh
                        setTimeout(() => findAndClickRefreshButton(), 1000);
                    }

                    clearInterval(readyCheckInterval);
                }
            }, 1000);
        }
    }

    function suppressErrors() {
    // Store original console error method
    const originalConsoleError = console.error;

    // Override console.error to filter out specific errors
    console.error = function(...args) {
        // Check if this is a DOM-related error we want to suppress
        const errorText = args.join(' ');
        if (errorText.includes('elementFinder') ||
            errorText.includes('Cannot read properties') ||
            errorText.includes('is not defined') ||
            errorText.includes('is null')) {
            // Silently ignore these errors
            return;
        }

        // Pass other errors through to the original method
        originalConsoleError.apply(console, args);
    };

    // Add global error handler
    window.addEventListener('error', function(event) {
        // Prevent the error from showing in console
        event.preventDefault();
        return true;
    }, true);

    // Add CSS to hide elementFinder displays - improved selectors
    const style = document.createElement('style');
    style.textContent = `
        /* Target the elementFinder display - more comprehensive selectors */
        div:not(#auto-refresh-container):has(span:contains("elementFinder")),
        div:not(#auto-refresh-container) > span:contains("elementFinder"),
        div:not(#auto-refresh-container):contains("elementFinder"),
        div:not(#auto-refresh-container):contains("/html/body/"),
        div:not(#auto-refresh-container):contains("soe-timespan-block"),
        body > div:last-of-type:not(#auto-refresh-container) {
            display: none !important;
            visibility: hidden !important;
            opacity: 0 !important;
            height: 0 !important;
            pointer-events: none !important;
            position: absolute !important;
            z-index: -9999 !important;
        }
    `;
    document.head.appendChild(style);

    // Function to actively remove elementFinder displays
    function removeElementFinderDisplays() {
        try {
            const allDivs = document.querySelectorAll('div:not(#auto-refresh-container)');

            for (const div of allDivs) {
                if (div.id === 'auto-refresh-container') continue;

                // Check for elementFinder text content - simplified to catch all variations
                const text = div.textContent || '';
                if (text.toLowerCase().includes('elementfinder') ||
                    text.includes('/html/body/') ||
                    text.includes('soe-timespan-block')) {

                    // Hide it first
                    div.style.display = 'none';
                    div.style.visibility = 'hidden';
                    div.style.opacity = '0';
                    div.style.height = '0';

                    // Try to remove it
                    try {
                        if (div.parentNode) {
                            div.parentNode.removeChild(div);
                        }
                    } catch (e) {
                        // If we can't remove it, at least it's hidden
                    }
                }
            }

            // Special check for elementFinder at bottom of page
            const bodyChildren = document.body.children;
            const lastChild = bodyChildren[bodyChildren.length - 1];

            if (lastChild && lastChild.id !== 'auto-refresh-container') {
                const text = lastChild.textContent || '';
                if (text.includes('elementFinder') || text.includes('/html/body/')) {
                    lastChild.style.display = 'none';
                    try {
                        document.body.removeChild(lastChild);
                    } catch (e) {
                        // Just hide it if we can't remove it
                    }
                }
            }
        } catch (e) {
            // Silent fail
        }
    }

    // Run removal immediately
    removeElementFinderDisplays();

    // Set up interval to constantly check for error displays
    setInterval(removeElementFinderDisplays, 200);

    // Set up mutation observer to detect when new error displays are added
    const observer = new MutationObserver((mutations) => {
        for (const mutation of mutations) {
            if (mutation.addedNodes.length) {
                removeElementFinderDisplays();
                break;
            }
        }
    });

    // Start observing the document body for changes
    observer.observe(document.body, {
        childList: true,
        subtree: true
    });
}

    // Apply error suppression
    suppressErrors();

    // Start the script when the window loads
    window.addEventListener('load', function() {
        console.log('Window loaded, running script...');
        initScript();
    });

})();