// SCToolbox WebView initialization script // Uses IPC (window.ipc.postMessage) to communicate with Rust backend (function () { 'use strict'; if (window._sctInitialized) return; window._sctInitialized = true; // ========== IPC Communication ========== // Send message to Rust backend function sendToRust(type, payload) { if (window.ipc && typeof window.ipc.postMessage === 'function') { window.ipc.postMessage(JSON.stringify({ type, payload })); } } // ========== 导航栏 UI ========== const icons = { back: '', forward: '', reload: '' }; // Global state from Rust window._sctNavState = { canGoBack: false, canGoForward: false, isLoading: true, url: window.location.href }; function createNavBar() { if (window.location.href === 'about:blank') return; if (document.getElementById('sct-navbar')) return; if (!document.body) { setTimeout(createNavBar, 50); return; } const nav = document.createElement('div'); nav.id = 'sct-navbar'; nav.innerHTML = `
Page icon
`; document.body.insertBefore(nav, document.body.firstChild); // Navigation buttons - send commands to Rust document.getElementById('sct-back').onclick = () => { sendToRust('nav_back', {}); }; document.getElementById('sct-forward').onclick = () => { sendToRust('nav_forward', {}); }; document.getElementById('sct-reload').onclick = () => { sendToRust('nav_reload', {}); }; // Apply initial state from Rust updateNavBarFromState(); // Request initial state from Rust sendToRust('get_nav_state', {}); } // Update navbar UI based on state from Rust function updateNavBarFromState() { const state = window._sctNavState; const backBtn = document.getElementById('sct-back'); const forwardBtn = document.getElementById('sct-forward'); const urlEl = document.getElementById('sct-navbar-url'); const spinner = document.getElementById('sct-spinner'); const faviconSlot = document.getElementById('sct-favicon-slot'); if (backBtn) { backBtn.disabled = !state.canGoBack; } if (forwardBtn) { forwardBtn.disabled = !state.canGoForward; } if (urlEl && state.url) { urlEl.value = state.url; } // Show spinner when loading, show favicon when complete if (state.isLoading) { if (spinner) { spinner.style.display = 'block'; spinner.setAttribute('aria-hidden', 'false'); spinner.setAttribute('aria-busy', 'true'); } if (faviconSlot) { faviconSlot.style.display = 'none'; } } else { if (spinner) { spinner.style.display = 'none'; spinner.setAttribute('aria-hidden', 'true'); spinner.setAttribute('aria-busy', 'false'); } // Show favicon when page is loaded showFaviconIfAvailable(); } } // Extract and show favicon from page function showFaviconIfAvailable() { const faviconSlot = document.getElementById('sct-favicon-slot'); const faviconImg = document.getElementById('sct-favicon'); if (!faviconSlot || !faviconImg) return; // Try to find favicon from page let faviconUrl = null; // 1. Look for link[rel="icon"] or link[rel="shortcut icon"] const linkIcon = document.querySelector('link[rel="icon"], link[rel="shortcut icon"], link[rel="apple-touch-icon"]'); if (linkIcon && linkIcon.href) { faviconUrl = linkIcon.href; } // 2. Look for og:image in meta tags (fallback) if (!faviconUrl) { const ogImage = document.querySelector('meta[property="og:image"]'); if (ogImage && ogImage.content) { faviconUrl = ogImage.content; } } // 3. Try default favicon.ico if (!faviconUrl) { try { const origin = window.location.origin; if (origin && origin !== 'null') { faviconUrl = origin + '/favicon.ico'; } } catch (e) { // Ignore } } // Display favicon if found if (faviconUrl) { faviconImg.src = faviconUrl; faviconImg.onerror = () => { faviconSlot.style.display = 'none'; }; faviconImg.onload = () => { faviconSlot.style.display = 'flex'; }; } else { faviconSlot.style.display = 'none'; } } // ========== Rust -> JS Message Handler ========== // Rust will call this function to update navigation state window._sctUpdateNavState = function (state) { if (state) { window._sctNavState = { canGoBack: !!state.can_go_back, canGoForward: !!state.can_go_forward, isLoading: !!state.is_loading, url: state.url || window.location.href }; updateNavBarFromState(); } }; // 在 DOM 准备好时创建导航栏 if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', createNavBar); } else { createNavBar(); } })();