From a9f756acb7f7eef83f18af802acb63219a0e7fb3 Mon Sep 17 00:00:00 2001 From: fofolee Date: Wed, 22 Jan 2025 15:17:20 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E8=8E=B7=E5=8F=96=E5=85=83?= =?UTF-8?q?=E7=B4=A0=E9=80=89=E6=8B=A9=E5=99=A8=E7=9A=84=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=EF=BC=9A=E5=9C=A8browser.js=E4=B8=AD=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E4=BA=86=20getSelector=20=E5=87=BD=E6=95=B0=EF=BC=8C=E5=85=81?= =?UTF-8?q?=E8=AE=B8=E7=94=A8=E6=88=B7=E7=9B=B4=E6=8E=A5=E5=9C=A8=E6=B5=8F?= =?UTF-8?q?=E8=A7=88=E5=99=A8=E4=B8=AD=E9=80=89=E6=8B=A9=E5=85=83=E7=B4=A0?= =?UTF-8?q?=E5=B9=B6=E8=BF=94=E5=9B=9E=E5=85=B6=E6=9C=80=E4=BC=98=E9=80=89?= =?UTF-8?q?=E6=8B=A9=E5=99=A8=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugin/lib/quickcomposer/browser/browser.js | 82 ++++++++++++++++++++- 1 file changed, 81 insertions(+), 1 deletion(-) diff --git a/plugin/lib/quickcomposer/browser/browser.js b/plugin/lib/quickcomposer/browser/browser.js index a632786..7ca06c3 100644 --- a/plugin/lib/quickcomposer/browser/browser.js +++ b/plugin/lib/quickcomposer/browser/browser.js @@ -201,7 +201,7 @@ const initCDP = async (port) => { } catch (err) { console.log(err); throw new Error( - `请确保浏览器已启动,且开启了远程调试端口(--remote-debugging-port=${port})` + `请先通过浏览器控制中的“启动浏览器”打开浏览器` ); } } @@ -376,6 +376,85 @@ const waitForElement = async (selector, timeout = 5000) => { throw new Error(`等待元素 ${selector} 超时`); }; +const getSelector = async () => { + return await executeScript(` + return new Promise((resolve) => { + // 创建高亮元素 + const highlight = document.createElement('div'); + highlight.style.cssText = 'position: fixed; pointer-events: none; z-index: 10000; background: rgba(130, 180, 230, 0.4); border: 2px solid rgba(130, 180, 230, 0.8); transition: all 0.2s;'; + document.body.appendChild(highlight); + + // 获取最优选择器 + function getOptimalSelector(element) { + if (!element || element === document.body) return null; + + // 尝试使用id + if (element.id) { + return '#' + element.id; + } + + // 尝试使用类名组合 + if (element.className && typeof element.className === 'string') { + const classes = element.className.trim().split(/\\s+/); + if (classes.length) { + const selector = '.' + classes.join('.'); + if (document.querySelectorAll(selector).length === 1) { + return selector; + } + } + } + + // 获取元素在同级中的索引 + const parent = element.parentElement; + if (!parent) return null; + + const siblings = Array.from(parent.children); + const index = siblings.indexOf(element); + + // 递归获取父元素选择器 + const parentSelector = getOptimalSelector(parent); + if (!parentSelector) return null; + + return \`\${parentSelector} > \${element.tagName.toLowerCase()}:nth-child(\${index + 1})\`; + } + + // 处理鼠标移动 + function handleMouseMove(e) { + const target = e.target; + if (!target || target === highlight) return; + + const rect = target.getBoundingClientRect(); + highlight.style.left = rect.left + 'px'; + highlight.style.top = rect.top + 'px'; + highlight.style.width = rect.width + 'px'; + highlight.style.height = rect.height + 'px'; + } + + // 处理点击 + function handleClick(e) { + e.preventDefault(); + e.stopPropagation(); + + const target = e.target; + if (!target || target === highlight) return; + + const selector = getOptimalSelector(target); + + // 清理 + document.removeEventListener('mousemove', handleMouseMove); + document.removeEventListener('click', handleClick, true); + highlight.remove(); + + resolve(selector); + return false; + } + + document.addEventListener('mousemove', handleMouseMove); + document.addEventListener('click', handleClick, true); + }); + `); +}; + module.exports = { launchBrowser, getUrl, @@ -397,4 +476,5 @@ module.exports = { getScrollPosition, getPageSize, waitForElement, + getSelector, };