From 42c935298011070c8357e2b23192d8253e78ecd8 Mon Sep 17 00:00:00 2001 From: "yinjun.chen1" Date: Wed, 16 Sep 2026 16:55:33 +0800 Subject: [PATCH] no message --- _locales/en/messages.json | 4 ++ _locales/zh_CN/messages.json | 4 ++ popup.css | 82 ++++++++++++++++++---- popup.html | 2 +- popup.js | 127 ++++++++++++++++++++--------------- 5 files changed, 151 insertions(+), 68 deletions(-) diff --git a/_locales/en/messages.json b/_locales/en/messages.json index 5e0a1d2..b6ce368 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -587,6 +587,10 @@ "message": "Edit", "description": "Edit button" }, + "moreActionsTitle": { + "message": "More actions", + "description": "More actions button title" + }, "toastEnabled": { "message": "Enabled", "description": "Toast - enabled" diff --git a/_locales/zh_CN/messages.json b/_locales/zh_CN/messages.json index 4d2745c..511e19c 100644 --- a/_locales/zh_CN/messages.json +++ b/_locales/zh_CN/messages.json @@ -587,6 +587,10 @@ "message": "编辑", "description": "编辑按钮" }, + "moreActionsTitle": { + "message": "更多操作", + "description": "更多操作按钮 title" + }, "toastEnabled": { "message": "已启用", "description": "toast - 已启用" diff --git a/popup.css b/popup.css index c1b7bf9..5244904 100644 --- a/popup.css +++ b/popup.css @@ -192,9 +192,6 @@ h2 { display: none; } -#cancelEditBtn { - padding: 4px 12px; -} .list-section { margin-bottom: 20px; @@ -209,14 +206,6 @@ h2 { flex-shrink: 0; } -/* 图标按钮 */ -.btn-icon { - padding: 5px; - display: inline-flex; - align-items: center; - justify-content: center; - line-height: 0; -} /* 内联展开式搜索框:点击搜索图标后向左展开 */ .search-box-inline { @@ -781,6 +770,11 @@ h2 { justify-content: space-between; align-items: center; gap: 8px; + cursor: pointer; +} + +.config-item:hover { + border-color: #e94560; } .config-info { @@ -810,8 +804,72 @@ h2 { .config-actions { display: flex; - gap: 6px; + gap: 4px; flex-shrink: 0; + position: relative; +} + +.btn-icon { + background: transparent; + border: none; + color: #a0a0b0; + cursor: pointer; + padding: 4px 6px; + border-radius: 6px; + display: flex; + align-items: center; + justify-content: center; + line-height: 0; + transition: background 0.2s, color 0.2s; +} + +.btn-icon:hover { + background: #0f3460; + color: #e94560; +} + +.config-menu { + position: absolute; + top: 100%; + right: 0; + margin-top: 4px; + background: #1a1a2e; + border: 1px solid #0f3460; + border-radius: 8px; + box-shadow: 0 4px 16px rgba(0, 0, 0, 0.45); + min-width: 120px; + display: none; + z-index: 100; + overflow: hidden; +} + +.config-menu.open { + display: block; +} + +.config-menu-item { + display: block; + width: 100%; + text-align: left; + background: transparent; + border: none; + color: #e0e0e0; + cursor: pointer; + padding: 8px 14px; + font-size: 12px; + white-space: nowrap; +} + +.config-menu-item:hover { + background: #0f3460; +} + +.config-menu-item.danger { + color: #e94560; +} + +.config-menu-item.danger:hover { + background: #3a0f1a; } .empty-msg { diff --git a/popup.html b/popup.html index 0285ba6..c4cacdb 100644 --- a/popup.html +++ b/popup.html @@ -46,7 +46,7 @@

添加域名配置

- +
diff --git a/popup.js b/popup.js index 6688eb6..89db6a0 100644 --- a/popup.js +++ b/popup.js @@ -57,8 +57,7 @@ document.addEventListener("DOMContentLoaded", () => { const passwordSelectorInput = $("passwordSelector"); const submitSelectorInput = $("submitSelector"); const addBtn = $("addBtn"); - const addConfigTitleEl = $("addConfigTitle"); - const cancelEditBtn = $("cancelEditBtn"); + const configList = $("configList"); const addSection = $("addSection"); const listSection = $("listSection"); @@ -138,7 +137,7 @@ document.addEventListener("DOMContentLoaded", () => { const strengthLabel = $("strengthLabel"); const crackTime = $("crackTime"); - let editingId = null; + let modalResolve = null; // 密码强度估算:按 GPU 集群约 10^7 次/秒(PBKDF2-SHA256)计 @@ -442,7 +441,6 @@ document.addEventListener("DOMContentLoaded", () => { submitSelector: submitSelectorInput.value, enabled: enabledCheckbox.checked, delayMs: delayMsInput.value, - editingId: editingId, }; chrome.storage.local.set({ [DRAFT_KEY]: draft }); } @@ -461,11 +459,7 @@ document.addEventListener("DOMContentLoaded", () => { submitSelectorInput.value = draft.submitSelector || ""; enabledCheckbox.checked = draft.enabled !== false; delayMsInput.value = draft.delayMs || ""; - editingId = null; - // 编辑已改为弹窗,顶部表单仅用于新增;忽略历史 draft 中的 editingId addBtn.textContent = t("addConfigBtn"); - addConfigTitleEl.textContent = t("addConfigTitle"); - cancelEditBtn.hidden = true; } function clearDraft() { @@ -661,6 +655,21 @@ document.addEventListener("DOMContentLoaded", () => { }); + function openConfigUrl(domain) { + if (!domain) return; + const url = /^https?:\/\//i.test(domain) ? domain : "http://" + domain; + window.open(url, "_blank", "noopener"); + } + + function closeAllMenus() { + document.querySelectorAll(".config-menu.open").forEach((m) => m.classList.remove("open")); + } + + document.addEventListener("click", (e) => { + if (!e.target.closest(".config-actions")) closeAllMenus(); + }); + + async function renderConfigList() { const allConfigs = await loadConfigs(); configList.innerHTML = ""; @@ -738,28 +747,15 @@ document.addEventListener("DOMContentLoaded", () => { const actions = document.createElement("div"); actions.className = "config-actions"; - - // 启用/禁用切换 - const toggleBtn = document.createElement("button"); - toggleBtn.className = "btn-toggle"; const isDisabled = cfg.enabled === false; - toggleBtn.textContent = isDisabled ? t("toggleEnable") : t("toggleDisable"); - toggleBtn.title = isDisabled ? t("toggleEnableTitle") : t("toggleDisableTitle"); - toggleBtn.addEventListener("click", async () => { - const updated = configs.map((c) => - c.id === cfg.id ? { ...c, enabled: c.enabled === false } : c - ); - await saveConfigs(updated); - renderConfigList(); - renderEnvSelect(); - if (envManageModal.classList.contains("show")) renderEnvManageList(); - showToast(isDisabled ? t("toastEnabled") : t("toastDisabled")); - }); + // 编辑(图标按钮) const editBtn = document.createElement("button"); - editBtn.className = "btn-edit"; - editBtn.textContent = t("editBtn"); - editBtn.addEventListener("click", () => { + editBtn.className = "btn-icon"; + editBtn.title = t("editBtn"); + editBtn.innerHTML = ''; + editBtn.addEventListener("click", (e) => { + e.stopPropagation(); editModalEditingId = cfg.id; editConfigModalTitle.textContent = t("editConfigTitle"); editConfigSave.textContent = t("updateConfigBtn"); @@ -777,24 +773,61 @@ document.addEventListener("DOMContentLoaded", () => { editDomainInput.focus(); }); - const delBtn = document.createElement("button"); - delBtn.className = "btn-danger"; - delBtn.textContent = t("deleteBtn"); - delBtn.addEventListener("click", async () => { + // 三个小点下拉菜单(收起禁用/删除) + const moreBtn = document.createElement("button"); + moreBtn.className = "btn-icon"; + moreBtn.title = t("moreActionsTitle"); + moreBtn.innerHTML = ''; + moreBtn.addEventListener("click", (e) => { + e.stopPropagation(); + const open = menu.classList.contains("open"); + closeAllMenus(); + if (!open) menu.classList.add("open"); + }); + + const menu = document.createElement("div"); + menu.className = "config-menu"; + + const toggleItem = document.createElement("button"); + toggleItem.className = "config-menu-item"; + toggleItem.textContent = isDisabled ? t("toggleEnable") : t("toggleDisable"); + toggleItem.addEventListener("click", async (e) => { + e.stopPropagation(); + closeAllMenus(); + const updated = configs.map((c) => + c.id === cfg.id ? { ...c, enabled: c.enabled === false } : c + ); + await saveConfigs(updated); + renderConfigList(); + renderEnvSelect(); + if (envManageModal.classList.contains("show")) renderEnvManageList(); + showToast(isDisabled ? t("toastEnabled") : t("toastDisabled")); + }); + + const delItem = document.createElement("button"); + delItem.className = "config-menu-item danger"; + delItem.textContent = t("deleteBtn"); + delItem.addEventListener("click", async (e) => { + e.stopPropagation(); + closeAllMenus(); const updated = configs.filter((c) => c.id !== cfg.id); await saveConfigs(updated); showToast(t("toastDeleted")); renderConfigList(); renderEnvSelect(); if (envManageModal.classList.contains("show")) renderEnvManageList(); - if (editingId === cfg.id) { - resetForm(); - } + }); - actions.appendChild(toggleBtn); + menu.appendChild(toggleItem); + menu.appendChild(delItem); actions.appendChild(editBtn); - actions.appendChild(delBtn); + actions.appendChild(moreBtn); + actions.appendChild(menu); + + // 点击整项 → 新窗口打开 + item.addEventListener("click", () => openConfigUrl(cfg.domain)); + item.appendChild(info); item.appendChild(actions); configList.appendChild(item); @@ -802,7 +835,6 @@ document.addEventListener("DOMContentLoaded", () => { } function resetForm() { - editingId = null; domainInput.value = ""; aliasInput.value = ""; usernameInput.value = ""; @@ -814,16 +846,10 @@ document.addEventListener("DOMContentLoaded", () => { enabledCheckbox.checked = true; delayMsInput.value = ""; addBtn.textContent = t("addConfigBtn"); - addConfigTitleEl.textContent = t("addConfigTitle"); - cancelEditBtn.hidden = true; clearDraft(); } - cancelEditBtn.addEventListener("click", () => { - resetForm(); - }); - addBtn.addEventListener("click", async () => { const domain = domainInput.value.trim(); const username = usernameInput.value.trim(); @@ -849,18 +875,9 @@ document.addEventListener("DOMContentLoaded", () => { const configs = await loadConfigs(); - if (editingId) { - const idx = configs.findIndex((c) => c.id === editingId); - if (idx !== -1) { - config.id = editingId; - configs[idx] = config; - } - showToast(t("toastUpdated")); - } else { - config.id = Date.now().toString(36) + Math.random().toString(36).slice(2, 8); - configs.push(config); - showToast(t("toastAdded")); - } + config.id = Date.now().toString(36) + Math.random().toString(36).slice(2, 8); + configs.push(config); + showToast(t("toastAdded")); await saveConfigs(configs); resetForm();