diff --git a/app/src/main/assets/h5/js/webapp/topbar.js b/app/src/main/assets/h5/js/webapp/topbar.js index 32ab714..e48d09f 100644 --- a/app/src/main/assets/h5/js/webapp/topbar.js +++ b/app/src/main/assets/h5/js/webapp/topbar.js @@ -12,18 +12,25 @@ window.showTopbar = function (tabs) { if (!bar) { bar = document.createElement('div'); bar.id = 'web-topbar'; - bar.innerHTML = ` - - - - - `; + const back = document.createElement('button'); + back.id = 'tb-back'; back.title = '回退'; back.textContent = '←'; + const fwd = document.createElement('button'); + fwd.id = 'tb-fwd'; fwd.title = '前进'; fwd.textContent = '→'; + const reload = document.createElement('button'); + reload.id = 'tb-reload'; reload.title = '重载'; reload.textContent = '⟳'; + const title = document.createElement('span'); + title.className = 'tb-title'; title.id = 'tb-title'; + const tabsBtn = document.createElement('button'); + tabsBtn.id = 'tb-tabs'; + bar.append(back, fwd, reload, title, tabsBtn); document.body.appendChild(bar); - document.getElementById('tb-back').onclick = () => bridge.call('webGoBack'); - document.getElementById('tb-fwd').onclick = () => bridge.call('webGoForward'); - document.getElementById('tb-reload').onclick = () => bridge.call('webReload'); - document.getElementById('tb-tabs').onclick = () => showTabPanel(tabs); + back.onclick = () => bridge.call('webGoBack'); + fwd.onclick = () => bridge.call('webGoForward'); + reload.onclick = () => bridge.call('webReload'); } + // 每次刷新都重绑,避免捕获旧 tabs(陈旧闭包) + // Rebind on every refresh to avoid capturing stale tabs (stale closure) + document.getElementById('tb-tabs').onclick = () => showTabPanel(tabs); document.getElementById('tb-tabs').textContent = `标签 (${tabs.length})`; const active = tabs.find(t => t.active); document.getElementById('tb-title').textContent = active ? active.name : ''; @@ -31,6 +38,8 @@ window.showTopbar = function (tabs) { // 标签面板:列出所有标签,点击切换,× 关闭 // Tab panel: list all tabs, click to switch, × to close +// 用 createElement + textContent/dataset 渲染,避免 innerHTML 拼接用户数据(XSS) +// Render with createElement + textContent/dataset to avoid innerHTML user data (XSS) function showTabPanel(tabs) { let panel = document.getElementById('tab-panel'); if (!panel) { @@ -38,15 +47,22 @@ function showTabPanel(tabs) { panel.id = 'tab-panel'; document.body.appendChild(panel); } - panel.innerHTML = tabs.map(t => ` -