no message
This commit is contained in:
@@ -587,6 +587,10 @@
|
||||
"message": "Edit",
|
||||
"description": "Edit button"
|
||||
},
|
||||
"moreActionsTitle": {
|
||||
"message": "More actions",
|
||||
"description": "More actions button title"
|
||||
},
|
||||
"toastEnabled": {
|
||||
"message": "Enabled",
|
||||
"description": "Toast - enabled"
|
||||
|
||||
@@ -587,6 +587,10 @@
|
||||
"message": "编辑",
|
||||
"description": "编辑按钮"
|
||||
},
|
||||
"moreActionsTitle": {
|
||||
"message": "更多操作",
|
||||
"description": "更多操作按钮 title"
|
||||
},
|
||||
"toastEnabled": {
|
||||
"message": "已启用",
|
||||
"description": "toast - 已启用"
|
||||
|
||||
@@ -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
@@ -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>
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user