fix: lazy-load ReferenceError + localize Font Awesome

- app.js: remove window.Dashboard=... block that crashed the whole
  file before page scripts load (ReferenceError: Dashboard is not
  defined). Page objects are top-level const in global lexical
  scope; PAGE_OBJS map + indirect eval in loadScript onload now
  expose them to window for inline onclick / data-action lookups
- index.html: Font Awesome 6.5.1 localized (css/fontawesome.min.css
  + 8 webfont files) - no more cdnjs CDN (Edge Tracking Prevention
  blocked it, CN access unstable)
This commit is contained in:
2026-08-22 19:29:24 +08:00
parent 4ebabfc703
commit e5a1d693f1
11 changed files with 51 additions and 29 deletions

View File

@@ -128,12 +128,49 @@ const App = {
bans: ['bans'],
logs: ['logs'],
},
// 脚本文件 → 顶层 const 页面对象(懒加载后经间接 eval 挂到 window)
PAGE_OBJS: {
'home.js': ['HomePage'],
'ticket-create.js': ['TicketCreate'],
'install.js': ['InstallPage'],
'login.js': ['LoginPage'],
'register.js': ['RegisterPage'],
'forgot.js': ['ForgotPage', 'ResetPage'],
'verify.js': ['VerifyPage'],
'dashboard.js': ['Dashboard'],
'unclaimed.js': ['UnclaimedPage'],
'tickets.js': ['TicketsPage'],
'ticket-detail.js': ['TicketDetail'],
'tracking.js': ['TrackingPage'],
'users.js': ['UsersPage'],
'notifications.js': ['NotificationsPage'],
'external-api.js': ['ExternalApiPage'],
'external-api-docs.js': ['ExternalApiDocsPage'],
'sources.js': ['SourcesPage'],
'templates.js': ['TemplatesPage'],
'settings-page.js': ['SettingsPage'],
'export-page.js': ['ExportPage'],
'polls.js': ['PollsPage'],
'features.js': ['FeaturesPage'],
'feature-detail.js': ['FeatureDetail'],
'servers.js': ['ServersPage'],
'bans.js': ['BansPage'],
'logs.js': ['LogsPage'],
},
loadScript(src) {
if (this._scriptCache[src]) return this._scriptCache[src];
const p = new Promise((resolve, reject) => {
const s = document.createElement('script');
s.src = src;
s.onload = () => resolve();
s.onload = () => {
// 页面脚本顶层 const 在全局词法环境, 用间接 eval 挂到 window,
// 供 inline onclick / data-action 的 window[obj] 查找
const objs = this.PAGE_OBJS[src.split('/').pop()] || [];
for (const o of objs) {
try { if (typeof window[o] === 'undefined') window[o] = (0, eval)(o); } catch {}
}
resolve();
};
s.onerror = () => { delete this._scriptCache[src]; reject(new Error('脚本加载失败: ' + src)); };
document.head.appendChild(s);
});
@@ -280,33 +317,8 @@ const App = {
};
document.addEventListener('DOMContentLoaded', () => App.init());
window.App = App;
window.Dashboard = Dashboard;
window.TicketsPage = TicketsPage;
window.TicketDetail = TicketDetail;
window.TicketCreate = TicketCreate;
window.TrackingPage = TrackingPage;
window.UnclaimedPage = UnclaimedPage;
window.UsersPage = UsersPage;
window.TemplatesPage = TemplatesPage;
window.NotificationsPage = NotificationsPage;
window.ExternalApiPage = ExternalApiPage;
window.SourcesPage = SourcesPage;
window.SettingsPage = SettingsPage;
window.ExportPage = ExportPage;
window.PollsPage = PollsPage;
window.FeaturesPage = FeaturesPage;
window.FeatureDetail = FeatureDetail;
window.ServersPage = ServersPage;
window.BansPage = BansPage;
window.LogsPage = LogsPage;
window.LoginPage = LoginPage;
window.RegisterPage = RegisterPage;
window.HomePage = HomePage;
window.InstallPage = InstallPage;
window.ForgotPage = ForgotPage;
window.ResetPage = ResetPage;
window.VerifyPage = VerifyPage;
// 页面对象(window.Dashboard 等)由各自脚本以顶层 const 定义, 全局词法环境可访问,
// 无需在此挂载(懒加载下此处引用会导致 ReferenceError 崩掉整个 app.js)
window.U = U;
window.Auth = Auth;
window.API = API;