no message

This commit is contained in:
yinjun.chen1
2026-09-16 15:27:18 +08:00
parent 8043d75e93
commit 0f2ceda59e
5 changed files with 84 additions and 27 deletions
+6 -6
View File
@@ -220,11 +220,11 @@
"description": "Username selector label"
},
"usernameSelectorPlaceholder": {
"message": "Empty=auto find, e.g. #username or input[name=account]",
"message": "Empty=auto find, or paste element HTML / CSS selector",
"description": "Username selector placeholder"
},
"usernameSelectorHelp": {
"message": "Leave empty. Wrong value will cause username not filled.",
"message": "Paste the input's DOM node, or a CSS selector; empty = auto find.",
"description": "Username selector help"
},
"passwordSelectorLabel": {
@@ -232,11 +232,11 @@
"description": "Password selector label"
},
"passwordSelectorPlaceholder": {
"message": "Empty=auto find, e.g. #password or input[type=password]",
"message": "Empty=auto find, or paste element HTML / CSS selector",
"description": "Password selector placeholder"
},
"passwordSelectorHelp": {
"message": "Leave empty. Wrong value will cause password not filled.",
"message": "Paste the input's DOM node, or a CSS selector; empty = auto find.",
"description": "Password selector help"
},
"submitSelectorLabel": {
@@ -244,11 +244,11 @@
"description": "Submit selector label"
},
"submitSelectorPlaceholder": {
"message": "Empty=auto find, e.g. #loginBtn or button[type=submit]",
"message": "Empty=auto find, or paste element HTML / CSS selector",
"description": "Submit selector placeholder"
},
"submitSelectorHelp": {
"message": "Leave empty. Wrong value will cause auto-submit not to click.",
"message": "Paste the button's DOM node, or a CSS selector; empty = auto find.",
"description": "Submit selector help"
},
"addConfigBtn": {
+6 -6
View File
@@ -220,11 +220,11 @@
"description": "用户名选择器 label"
},
"usernameSelectorPlaceholder": {
"message": "留空=自动查找,如 #username 或 input[name=account]",
"message": "留空=自动查找,可粘贴元素 HTML 或填 CSS 选择器",
"description": "用户名选择器 placeholder"
},
"usernameSelectorHelp": {
"message": "留空即可。填错会导致用户名填不进框。",
"message": "直接粘贴该输入框的 DOM 节点,或填 CSS 选择器;留空则自动查找。",
"description": "用户名选择器下方说明"
},
"passwordSelectorLabel": {
@@ -232,11 +232,11 @@
"description": "密码选择器 label"
},
"passwordSelectorPlaceholder": {
"message": "留空=自动查找,如 #password 或 input[type=password]",
"message": "留空=自动查找,可粘贴元素 HTML 或填 CSS 选择器",
"description": "密码选择器 placeholder"
},
"passwordSelectorHelp": {
"message": "留空即可。填错会导致密码填不进框。",
"message": "直接粘贴该输入框的 DOM 节点,或填 CSS 选择器;留空则自动查找。",
"description": "密码选择器下方说明"
},
"submitSelectorLabel": {
@@ -244,11 +244,11 @@
"description": "登录按钮选择器 label"
},
"submitSelectorPlaceholder": {
"message": "留空=自动查找,如 #loginBtn 或 button[type=submit]",
"message": "留空=自动查找,可粘贴元素 HTML 或填 CSS 选择器",
"description": "登录按钮选择器 placeholder"
},
"submitSelectorHelp": {
"message": "留空即可。填错会导致不会自动点击登录。",
"message": "直接粘贴该按钮的 DOM 节点,或填 CSS 选择器;留空则自动查找。",
"description": "登录按钮选择器下方说明"
},
"addConfigBtn": {
+64 -10
View File
@@ -71,13 +71,49 @@ function setNativeValue(el, value) {
el.dispatchEvent(new Event("change", { bubbles: true }));
}
function resolveElement(value, multiple) {
if (!value) return null;
const trimmed = value.trim();
if (!trimmed.startsWith("<")) {
return multiple ? Array.from(document.querySelectorAll(trimmed)) : document.querySelector(trimmed);
}
const doc = new DOMParser().parseFromString(trimmed, "text/html");
const el = doc.body.firstElementChild;
if (!el) return null;
const tag = el.tagName.toLowerCase();
const id = el.id;
const cls = Array.from(el.classList);
const type = el.getAttribute("type");
const nameAttr = el.getAttribute("name");
const candidates = [];
if (id) candidates.push(`${tag}#${CSS.escape(id)}`);
if (cls.length) candidates.push(`${tag}.${cls.map(CSS.escape).join(".")}`);
if (type) candidates.push(`${tag}[type="${type}"]`);
if (nameAttr) candidates.push(`${tag}[name="${CSS.escape(nameAttr)}"]`);
for (const c of cls) candidates.push(`${tag}.${CSS.escape(c)}`);
candidates.push(tag);
for (const sel of candidates) {
if (multiple) {
const els = Array.from(document.querySelectorAll(sel));
if (els.length) return els;
} else {
const found = document.querySelector(sel);
if (found) return found;
}
}
return null;
}
function findUsernameField(config) {
let searchScope = config.usernameSelector ? document.querySelector(config.usernameSelector) : null;
if (!searchScope) {
if (config.usernameSelector) {
const el = resolveElement(config.usernameSelector);
if (el) return el;
}
const passwordField = findPasswordField(config);
if (!passwordField) return null;
searchScope = passwordField.closest("form") || document;
}
const searchScope = passwordField.closest("form") || document;
const selectors = [
"input[type='text']",
@@ -125,8 +161,12 @@ function findUsernameField(config) {
}
function findPasswordField(config) {
const scope = config.passwordSelector ? (document.querySelector(config.passwordSelector) || document) : document;
const passwordInputs = scope.querySelectorAll("input[type='password']");
if (config.passwordSelector) {
const el = resolveElement(config.passwordSelector);
if (el) return el;
}
const passwordInputs = document.querySelectorAll("input[type='password']");
for (const input of passwordInputs) {
if (input.offsetParent !== null || input.offsetWidth > 0) {
return input;
@@ -137,11 +177,25 @@ function findPasswordField(config) {
}
function findSubmitButton(config, passwordField) {
let searchScope = config.submitSelector ? document.querySelector(config.submitSelector) : null;
if (!searchScope) {
const form = passwordField ? passwordField.closest("form") : null;
searchScope = form || document;
if (config.submitSelector) {
const els = resolveElement(config.submitSelector, true);
if (els && els.length === 1) return els[0];
if (els && els.length > 1) {
for (const el of els) {
if (el.offsetParent === null && el.offsetWidth === 0) continue;
const compact = (el.textContent || el.value || "").toLowerCase().replace(/\s/g, "");
if (compact.includes("登录") || compact.includes("login") || compact.includes("signin")) {
return el;
}
}
for (const el of els) {
if (el.offsetParent !== null || el.offsetWidth > 0) return el;
}
}
}
const form = passwordField ? passwordField.closest("form") : null;
const searchScope = form || document;
const submitSelectors = [
"button[type='submit']",
+1
View File
@@ -1052,6 +1052,7 @@ document.addEventListener("DOMContentLoaded", () => {
}
const value = u.pathname && u.pathname !== "/" ? host + u.pathname : host;
domainInput.value = value;
if (tab.title) aliasInput.value = tab.title;
saveDraft();
showToast(t("toastDomainFilled", value));
} catch {
+5 -3
View File
@@ -19,18 +19,20 @@
if (!url || !pattern) return false;
try {
const u = new URL(url);
const hostname = u.hostname;
const rawPattern = String(pattern).trim();
if (rawPattern.includes("/")) {
const slashIdx = rawPattern.indexOf("/");
const hostPart = rawPattern.slice(0, slashIdx);
const pathPart = rawPattern.slice(slashIdx + 1) || "";
if (!matchHost(hostname, hostPart)) return false;
const hostForMatch = hostPart.includes(":") ? u.host : u.hostname;
if (!matchHost(hostForMatch, hostPart)) return false;
return matchPath(u.pathname, pathPart);
}
return matchHost(hostname, rawPattern);
const hostForMatch = rawPattern.includes(":") ? u.host : u.hostname;
return matchHost(hostForMatch, rawPattern);
} catch {
return false;
}