PageSourceSearch

https://fangg.netlify.app/js/apps/ie.js

js fangg.netlify.app collected 2026-10-03 10:43:39 UTC 5,158 bytes, 183 lines download raw bytes

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.