no message

This commit is contained in:
yinjun.chen1
2026-09-16 16:55:33 +08:00
parent 1df875b297
commit 42c9352980
5 changed files with 151 additions and 68 deletions
+4
View File
@@ -587,6 +587,10 @@
"message": "Edit",
"description": "Edit button"
},
"moreActionsTitle": {
"message": "More actions",
"description": "More actions button title"
},
"toastEnabled": {
"message": "Enabled",
"description": "Toast - enabled"
+4
View File
@@ -587,6 +587,10 @@
"message": "编辑",
"description": "编辑按钮"
},
"moreActionsTitle": {
"message": "更多操作",
"description": "更多操作按钮 title"
},
"toastEnabled": {
"message": "已启用",
"description": "toast - 已启用"
+70 -12
View File
@@ -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 {
+1 -1
View File
@@ -46,7 +46,7 @@
<button type="button" id="addEntryBtn" class="btn-primary" data-i18n="addConfigTitle">添加域名配置</button>
<div class="add-section-header">
<h2 id="addConfigTitle" data-i18n="addConfigTitle">添加域名配置</h2>
<button type="button" id="cancelEditBtn" class="btn-edit" data-i18n="cancelBtn" hidden>取消</button>
</div>
<div class="form-group">
<label for="domain" data-i18n="domainLabel">域名 / URL 匹配规则</label>
+69 -52
View File
@@ -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 = '<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 20h9"/><path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z"/></svg>';
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 = '<svg viewBox="0 0 24 24" width="14" height="14" fill="currentColor"><circle cx="12" cy="5" r="1.6"/><circle cx="12" cy="12" r="1.6"/><circle cx="12" cy="19" r="1.6"/></svg>';
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"));
}
await saveConfigs(configs);
resetForm();