1(function () { 2 const WINDOW_ID = 'ie'; 3 const IFRAME_ID = 'ie-iframe'; 4 const ADDRESS_ID = 'ie-address-input'; 5 const STATUS_LEFT_ID = 'ie-status-left'; 6 const STATUS_RIGHT_ID = 'ie-status-right'; 7 8 const HOME_URL = 'https://www.4399.com/'; 9 10 let historyStack = []; 11 let forwardStack = []; 12 13 function getEl(id) { 14 return document.getElementById(id); 15 } 16 17 function normalizeInputToUrl(input) { 18 const trimmed = input.trim(); 19 if (trimmed === '') return ''; 20 try { 21 // Already a valid URL with protocol 22 const url = new URL(trimmed); 23 return url.toString(); 24 } catch (_) { 25 // If looks like domain without protocol (optionally with path) 26 if (/^[\w.-]+\.[a-zA-Z]{2,}(\/.*)?$/.test(trimmed)) { 27 return 'https://' + trimmed; 28 } 29 // Fallback: search query 30 const q = encodeURIComponent(trimmed); 31 return `https://www.4399.com/s?k=${q}`; 32 } 33 } 34 35 function updateButtons() { 36 const backBtn = getEl('ie-back'); 37 const forwardBtn = getEl('ie-forward'); 38 if (backBtn) backBtn.disabled = historyStack.length <= 1; 39 if (forwardBtn) forwardBtn.disabled = forwardStack.length === 0; 40 } 41 42 function setStatus(textLeft, textRight = '') { 43 const left = getEl(STATUS_LEFT_ID); 44 const right = getEl(STATUS_RIGHT_ID); 45 if (left) left.textContent = textLeft || ''; 46 if (right) right.textContent = textRight || ''; 47 } 48 49 function navigateTo(input, pushHistory = true) { 50 const iframe = getEl(IFRAME_ID); 51 const address = getEl(ADDRESS_ID); 52 if (!iframe || !address) return; 53 54 const url = normalizeInputToUrl(input); 55 if (!url) return; 56 57 if (pushHistory) { 58 if (historyStack.length === 0 || historyStack[historyStack.length - 1] !== url) { 59 historyStack.push(url); 60 } 61 // New navigation clears forward stack 62 forwardStack = []; 63 } 64 65 address.value = url; 66 setStatus('æ£å¨è½½å ¥...', url); 67 iframe.src = url; 68 updateButtons(); 69 } 70 71 function goBack() { 72 if (historyStack.length <= 1) return; 73 const current = historyStack.pop(); 74 if (current) forwardStack.push(current); 75 const previous = historyStack[historyStack.length - 1]; 76 navigateTo(previous, false); 77 } 78 79 function goForward() { 80 if (forwardStack.length === 0) return; 81 const next = forwardStack.pop(); 82 if (next) { 83 historyStack.push(next); 84 navigateTo(next, false); 85 } 86 } 87 88 function refresh() { 89 const iframe = getEl(IFRAME_ID); 90 if (!iframe) return; 91 try { 92 const currentUrl = iframe.src; 93 if (currentUrl) { 94 setStatus('æ£å¨éæ°æ´ç...', currentUrl); 95 iframe.src = currentUrl; 96 } 97 } catch (_) {} 98 } 99 100 function openHome() { 101 navigateTo(HOME_URL, true); 102 } 103 104 function openExternalTab() { 105 const address = getEl(ADDRESS_ID); 106 const url = address ? normalizeInputToUrl(address.value) : HOME_URL; 107 try { 108 window.open(url, '_blank', 'noopener'); 109 } catch (_) {} 110 } 111 112 function bindEvents() { 113 const backBtn = getEl('ie-back'); 114 const forwardBtn = getEl('ie-forward'); 115 const refreshBtn = getEl('ie-refresh'); 116 const homeBtn = getEl('ie-home'); 117 const goBtn = getEl('ie-go'); 118 const externalBtn = getEl('ie-open-external'); 119 const address = getEl(ADDRESS_ID); 120 const iframe = getEl(IFRAME_ID); 121 122 if (backBtn) backBtn.addEventListener('click', goBack); 123 if (forwardBtn) forwardBtn.addEventListener('click', goForward); 124 if (refreshBtn) refreshBtn.addEventListener('click', refresh); 125 if (homeBtn) homeBtn.addEventListener('click', openHome); 126 if (goBtn) goBtn.addEventListener('click', () => navigateTo(address.value, true)); 127 if (externalBtn) externalBtn.addEventListener('click', openExternalTab); 128 129 if (address) { 130 address.addEventListener('keydown', (e) => { 131 if (e.key === 'Enter') { 132 navigateTo(address.value, true); 133 } 134 }); 135 } 136 137 if (iframe) { 138 iframe.addEventListener('load', () => { 139 try { 140 const currentUrl = iframe.src; 141 setStatus('宿', currentUrl); 142 // Sync address bar if changed by redirects 143 const addressEl = getEl(ADDRESS_ID); 144 if (addressEl && currentUrl) addressEl.value = currentUrl; 145 } catch (_) { 146 setStatus('宿'); 147 } 148 }); 149 } 150 } 151
152 function init() { 153 bindEvents(); 154 // default load home once 155 const iframe = getEl(IFRAME_ID); 156 if (iframe && !iframe.src) navigateTo(HOME_URL, true); 157 } 158 159 // Register open function for consistency (optional) 160 window.openIE = function openIE() { 161 if (typeof window.openWindow === 'function') { 162 window.openWindow(WINDOW_ID); 163 } 164 }; 165 166 // Expose navigate function for other apps (e.g., bookmarks) to open URL inside IE window 167 window.navigateIE = function navigateIE(urlOrQuery) { 168 try { 169 if (typeof window.openWindow === 'function') { 170 window.openWindow(WINDOW_ID); 171 } 172 navigateTo(urlOrQuery, true); 173 } catch (_) {} 174 }; 175 176 if (document.readyState === 'loading') { 177 document.addEventListener('DOMContentLoaded', init); 178 } else { 179 init(); 180 } 181})(); 182 183
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.