opt xpath

This commit is contained in:
jianxin committed 2024-12-18 08:41:50 +08:00
1 parent 3f045f11e8
commit 7fb6d04b19
6 files changed
+358 -358

No files matched your search

+63 -63
View File
@@ -1,63 +1,63 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<title>影刀 PY 助手</title> <title>影刀 PY 助手</title>
<style> <style>
body { body {
font-family: Arial, sans-serif; font-family: Arial, sans-serif;
padding: 10px; padding: 10px;
} }
.switch { .switch {
position: relative; position: relative;
display: inline-block; display: inline-block;
width: 60px; width: 60px;
height: 34px; height: 34px;
} }
.switch input { .switch input {
opacity: 0; opacity: 0;
width: 0; width: 0;
height: 0; height: 0;
} }
.slider { .slider {
position: absolute; position: absolute;
cursor: pointer; cursor: pointer;
top: 0; top: 0;
left: 0; left: 0;
right: 0; right: 0;
bottom: 0; bottom: 0;
background-color: #ccc; background-color: #ccc;
transition: .4s; transition: .4s;
} }
.slider:before { .slider:before {
position: absolute; position: absolute;
content: ""; content: "";
height: 26px; height: 26px;
width: 26px; width: 26px;
left: 4px; left: 4px;
bottom: 4px; bottom: 4px;
background-color: white; background-color: white;
transition: .4s; transition: .4s;
} }
input:checked + .slider { input:checked + .slider {
background-color: #2196F3; background-color: #2196F3;
} }
input:checked + .slider:before { input:checked + .slider:before {
transform: translateX(26px); transform: translateX(26px);
} }
.slider.round { .slider.round {
border-radius: 34px; border-radius: 34px;
} }
.slider.round:before { .slider.round:before {
border-radius: 50%; border-radius: 50%;
} }
</style> </style>
</head> </head>
<body> <body>
<label class="switch"> <label class="switch">
<input type="checkbox" id="toggleCopyMode"> <input type="checkbox" id="toggleCopyMode">
<span class="slider round"></span> <span class="slider round"></span>
</label> </label>
<p id="statusText">Copy mode is off</p> <p id="statusText">Copy mode is off</p>
<script src="scripts/popup.js"></script> <script src="scripts/popup.js"></script>
</body> </body>
</html> </html>
+40 -40
View File
@@ -1,40 +1,40 @@
{ {
"name": "Xbot PY Helper", "name": "Xbot PY Helper",
"description": "自动生成 网页自动化代码", "description": "自动生成 网页自动化代码",
"version": "0.1.2", "version": "0.1.2",
"manifest_version": 3, "manifest_version": 3,
"permissions": [ "permissions": [
"activeTab", "activeTab",
"scripting", "scripting",
"clipboardWrite" "clipboardWrite"
], ],
"background": { "background": {
"service_worker": "scripts/background.js" "service_worker": "scripts/background.js"
}, },
"action": { "action": {
"default_popup": "index.html", "default_popup": "index.html",
"default_icon": "images/yingdao-16x16.png" "default_icon": "images/yingdao-16x16.png"
}, },
"content_scripts": [ "content_scripts": [
{ {
"matches": [ "matches": [
"<all_urls>" "<all_urls>"
], ],
"js": [ "js": [
"scripts/content.js" "scripts/content.js"
], ],
"run_at": "document_idle", "run_at": "document_idle",
"all_frames": true "all_frames": true
} }
], ],
"web_accessible_resources": [ "web_accessible_resources": [
{ {
"resources": [ "resources": [
"scripts/popup.js" "scripts/popup.js"
], ],
"matches": [ "matches": [
"<all_urls>" "<all_urls>"
] ]
} }
] ]
} }
+12 -12
View File
@@ -1,12 +1,12 @@
# 影刀YD助手 # 影刀YD助手
## 项目介绍 ## 项目介绍
## 功能介绍 ## 功能介绍
鼠标悬浮到元素上, 自动生成影刀代码 鼠标悬浮到元素上, 自动生成影刀代码
## 优化项目 ## 优化项目
1. 生成xpath的规则 1. 生成xpath的规则
2. 支持跨域 2. 支持跨域
3. 支持开始和关闭拷贝模式 3. 支持开始和关闭拷贝模式
+32 -32
View File
@@ -1,32 +1,32 @@
let isCopyModeEnabled = false; let isCopyModeEnabled = false;
chrome.action.onClicked.addListener(function (tab) { chrome.action.onClicked.addListener(function (tab) {
chrome.scripting.executeScript({ chrome.scripting.executeScript({
target: { tabId: tab.id }, target: { tabId: tab.id },
function: toggleCopyMode function: toggleCopyMode
}); });
}); });
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) { chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
if (request.action === 'toggleCopyMode') { if (request.action === 'toggleCopyMode') {
isCopyModeEnabled = !isCopyModeEnabled; isCopyModeEnabled = !isCopyModeEnabled;
chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) { chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
chrome.tabs.sendMessage(tabs[0].id, { action: 'toggleCopyMode' }, function (response) { chrome.tabs.sendMessage(tabs[0].id, { action: 'toggleCopyMode' }, function (response) {
sendResponse({ copyModeEnabled: isCopyModeEnabled }); sendResponse({ copyModeEnabled: isCopyModeEnabled });
}); });
}); });
return true; // Keep the message channel open for sendResponse return true; // Keep the message channel open for sendResponse
} else if (request.action === 'getCopyModeStatus') { } else if (request.action === 'getCopyModeStatus') {
sendResponse({ copyModeEnabled: isCopyModeEnabled }); sendResponse({ copyModeEnabled: isCopyModeEnabled });
} }
}); });
function toggleCopyMode() { function toggleCopyMode() {
chrome.runtime.sendMessage({ action: 'toggleCopyMode' }, function (response) { chrome.runtime.sendMessage({ action: 'toggleCopyMode' }, function (response) {
if (response.copyModeEnabled) { if (response.copyModeEnabled) {
console.log('Copy mode enabled'); console.log('Copy mode enabled');
} else { } else {
console.log('Copy mode disabled'); console.log('Copy mode disabled');
} }
}); });
} }
+191 -191
View File
@@ -1,191 +1,191 @@
(function () { (function () {
console.log("Content script injected into:", window.location.href); console.log("Content script injected into:", window.location.href);
// 清除之前的高亮样式 // 清除之前的高亮样式
let previousHighlight = null; let previousHighlight = null;
let copyButton = null; let copyButton = null;
let isCopyModeEnabled = false; let isCopyModeEnabled = false;
let copyMessage = null; let copyMessage = null;
// 创建复制按钮 // 创建复制按钮
function createCopyButton() { function createCopyButton() {
const button = document.createElement('button'); const button = document.createElement('button');
button.innerHTML = '📋'; // 使用图标展示拷贝 button.innerHTML = '📋'; // 使用图标展示拷贝
button.style.position = 'absolute'; button.style.position = 'absolute';
button.style.zIndex = '1000'; button.style.zIndex = '1000';
button.style.display = 'none'; button.style.display = 'none';
button.style.background = 'transparent'; button.style.background = 'transparent';
button.style.border = 'none'; button.style.border = 'none';
button.style.cursor = 'pointer'; button.style.cursor = 'pointer';
button.style.fontSize = '16px'; button.style.fontSize = '16px';
button.addEventListener('click', function () { button.addEventListener('click', function () {
if (previousHighlight) { if (previousHighlight) {
const xpath = getElementXPath(previousHighlight); const xpath = getElementXPath(previousHighlight);
const action = previousHighlight.tagName.toLowerCase() === 'input' ? 'input("your_text")' : 'click()'; const action = previousHighlight.tagName.toLowerCase() === 'input' ? 'input("your_text")' : 'click()';
const command = `web.find_by_xpath("${xpath}").${action}`; const command = `web.find_by_xpath("${xpath}").${action}`;
navigator.clipboard.writeText(command).then(() => { navigator.clipboard.writeText(command).then(() => {
console.log('Command copied to clipboard:', command); console.log('Command copied to clipboard:', command);
copyMessage.style.display = 'block'; copyMessage.style.display = 'block';
setTimeout(() => { setTimeout(() => {
copyMessage.style.display = 'none'; copyMessage.style.display = 'none';
}, 3000); }, 3000);
}); });
} }
}); });
document.body.appendChild(button); document.body.appendChild(button);
return button; return button;
} }
// 创建复制消息提示 // 创建复制消息提示
function createCopyMessage() { function createCopyMessage() {
const message = document.createElement('div'); const message = document.createElement('div');
message.innerHTML = '已拷贝! <span id="copied-xpath" style="color:rgb(191, 201, 214);"></span><span style="cursor: pointer;">x</span> '; message.innerHTML = '已拷贝! <span id="copied-xpath" style="color:rgb(191, 201, 214);"></span><span style="cursor: pointer;">x</span> ';
message.style.position = 'fixed'; message.style.position = 'fixed';
message.style.top = '10px'; message.style.top = '10px';
message.style.left = '50%'; message.style.left = '50%';
message.style.transform = 'translateX(-50%)'; message.style.transform = 'translateX(-50%)';
message.style.background = '#1E3A8A'; message.style.background = '#1E3A8A';
message.style.color = '#F9FAFB'; message.style.color = '#F9FAFB';
message.style.padding = '10px'; message.style.padding = '10px';
message.style.borderRadius = '5px'; message.style.borderRadius = '5px';
message.style.display = 'none'; message.style.display = 'none';
message.style.zIndex = '1001'; message.style.zIndex = '1001';
message.style.fontSize = '16px'; // 增大字体 message.style.fontSize = '16px'; // 增大字体
message.querySelector('span').addEventListener('click', function () { message.querySelector('span').addEventListener('click', function () {
message.style.display = 'none'; message.style.display = 'none';
}); });
document.body.appendChild(message); document.body.appendChild(message);
return message; return message;
} }
// 获取元素的 XPath // 获取元素的 XPath
function getElementXPath(element) { function getElementXPath(element) {
if (element.id) { if (element.id) {
return `//*[@id="${element.id}"]`; return `//*[@id="${element.id}"]`;
} }
const parts = []; const parts = [];
while (element && element.nodeType === Node.ELEMENT_NODE) { while (element && element.nodeType === Node.ELEMENT_NODE) {
let selector = element.nodeName.toLowerCase(); let selector = element.nodeName.toLowerCase();
if (element.className) { if (element.className) {
selector += `[@class="${element.className}"]`; selector += `[@class="${element.className}"]`;
} else if (element.textContent.trim()) { } else if (element.textContent.trim()) {
selector += `[text()="${element.textContent.trim()}"]`; selector += `[text()="${element.textContent.trim()}"]`;
} else if (element.id) { } else if (element.id) {
selector += `[@id="${element.id}"]`; selector += `[@id="${element.id}"]`;
} else { } else {
let sibling = element; let sibling = element;
let index = 1; let index = 1;
while (sibling.previousElementSibling) { while (sibling.previousElementSibling) {
sibling = sibling.previousElementSibling; sibling = sibling.previousElementSibling;
if (sibling.nodeName.toLowerCase() === selector) { if (sibling.nodeName.toLowerCase() === selector) {
index++; index++;
} }
} }
selector += `[${index}]`; selector += `[${index}]`;
} }
parts.unshift(selector); parts.unshift(selector);
element = element.parentNode; element = element.parentNode;
} }
return parts.length ? '/' + parts.join('/') : null; return parts.length ? '/' + parts.join('/') : null;
} }
// 监听鼠标移动事件 // 监听鼠标移动事件
document.addEventListener('mousemove', function (event) { document.addEventListener('mousemove', function (event) {
if (!isCopyModeEnabled) return; if (!isCopyModeEnabled) return;
// 移除上一次高亮 // 移除上一次高亮
if (previousHighlight) { if (previousHighlight) {
previousHighlight.style.background = ''; previousHighlight.style.background = '';
previousHighlight.style.backgroundImage = ''; previousHighlight.style.backgroundImage = '';
previousHighlight.style.border = ''; previousHighlight.style.border = '';
copyButton.style.display = 'none'; copyButton.style.display = 'none';
} }
// 获取鼠标位置 // 获取鼠标位置
const mouseX = event.clientX; const mouseX = event.clientX;
const mouseY = event.clientY; const mouseY = event.clientY;
// 获取鼠标下的元素 // 获取鼠标下的元素
const element = document.elementFromPoint(mouseX, mouseY); const element = document.elementFromPoint(mouseX, mouseY);
// 如果有元素,添加高亮样式并输出对应的 XPath // 如果有元素,添加高亮样式并输出对应的 XPath
if (element && element !== document.body) { if (element && element !== document.body) {
previousHighlight = element; previousHighlight = element;
element.style.background = 'rgba(255, 182, 193, 0.5)'; // 浅红色背景 element.style.background = 'rgba(255, 182, 193, 0.5)'; // 浅红色背景
element.style.backgroundImage = 'linear-gradient(45deg, rgba(255, 182, 193, 0.5) 25%, transparent 25%, transparent 50%, rgba(255, 182, 193, 0.5) 50%, rgba(255, 182, 193, 0.5) 75%, transparent 75%, transparent)'; // 浅红色斜线 element.style.backgroundImage = 'linear-gradient(45deg, rgba(255, 182, 193, 0.5) 25%, transparent 25%, transparent 50%, rgba(255, 182, 193, 0.5) 50%, rgba(255, 182, 193, 0.5) 75%, transparent 75%, transparent)'; // 浅红色斜线
element.style.backgroundSize = '10px 10px'; element.style.backgroundSize = '10px 10px';
element.style.border = '2px solid rgba(255, 105, 135, 0.8)'; // 边框颜色稍深 element.style.border = '2px solid rgba(255, 105, 135, 0.8)'; // 边框颜色稍深
element.style.borderRadius = '5px'; element.style.borderRadius = '5px';
// 设置复制按钮位置并显示 // 设置复制按钮位置并显示
const rect = element.getBoundingClientRect(); const rect = element.getBoundingClientRect();
copyButton.style.left = `${rect.right + window.scrollX - 20}px`; copyButton.style.left = `${rect.right + window.scrollX - 20}px`;
copyButton.style.top = `${rect.top + window.scrollY}px`; copyButton.style.top = `${rect.top + window.scrollY}px`;
copyButton.style.display = 'block'; copyButton.style.display = 'block';
// 输出 XPath // 输出 XPath
const xpath = getElementXPath(element); const xpath = getElementXPath(element);
console.log('Element XPath:', xpath); console.log('Element XPath:', xpath);
} }
}); });
// 监听消息以启用或禁用拷贝模式 // 监听消息以启用或禁用拷贝模式
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) { chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
if (request.action === 'toggleCopyMode') { if (request.action === 'toggleCopyMode') {
isCopyModeEnabled = !isCopyModeEnabled; isCopyModeEnabled = !isCopyModeEnabled;
if (!isCopyModeEnabled && previousHighlight) { if (!isCopyModeEnabled && previousHighlight) {
previousHighlight.style.border = ''; previousHighlight.style.border = '';
previousHighlight.style.borderRadius = ''; previousHighlight.style.borderRadius = '';
previousHighlight.style.boxShadow = ''; previousHighlight.style.boxShadow = '';
copyButton.style.display = 'none'; copyButton.style.display = 'none';
} }
sendResponse({ copyModeEnabled: isCopyModeEnabled }); sendResponse({ copyModeEnabled: isCopyModeEnabled });
} }
}); });
// 监听键盘事件以启用或禁用拷贝模式 // 监听键盘事件以启用或禁用拷贝模式
document.addEventListener('keydown', function (event) { document.addEventListener('keydown', function (event) {
console.log(event.key); console.log(event.key);
if (event.altKey && event.key === 'r') { if (event.altKey && event.key === 'r') {
isCopyModeEnabled = true; isCopyModeEnabled = true;
console.log('Copy mode enabled'); console.log('Copy mode enabled');
} else if (event.key === 'Escape') { } else if (event.key === 'Escape') {
isCopyModeEnabled = false; isCopyModeEnabled = false;
if (previousHighlight) { if (previousHighlight) {
previousHighlight.style.background = ''; previousHighlight.style.background = '';
previousHighlight.style.backgroundImage = ''; previousHighlight.style.backgroundImage = '';
previousHighlight.style.border = ''; previousHighlight.style.border = '';
copyButton.style.display = 'none'; copyButton.style.display = 'none';
previousHighlight = null; previousHighlight = null;
} }
console.log('Copy mode disabled'); console.log('Copy mode disabled');
} else if (event.ctrlKey && event.key === 'c' && previousHighlight) { } else if (event.ctrlKey && event.key === 'c' && previousHighlight) {
const xpath = getElementXPath(previousHighlight); const xpath = getElementXPath(previousHighlight);
const action = previousHighlight.tagName.toLowerCase() === 'input' ? 'input("your_text")' : 'click()'; const action = previousHighlight.tagName.toLowerCase() === 'input' ? 'input("your_text")' : 'click()';
const command = `web.find_by_xpath("${xpath}").${action}`; const command = `web.find_by_xpath("${xpath}").${action}`;
navigator.clipboard.writeText(command).then(() => { navigator.clipboard.writeText(command).then(() => {
console.log('Command copied to clipboard:', command); console.log('Command copied to clipboard:', command);
const truncatedXPath = xpath.length > 20 ? xpath.substring(0, 20) + '...' : xpath; const truncatedXPath = xpath.length > 20 ? xpath.substring(0, 20) + '...' : xpath;
document.getElementById('copied-xpath').innerText = truncatedXPath; document.getElementById('copied-xpath').innerText = truncatedXPath;
copyMessage.style.display = 'block'; copyMessage.style.display = 'block';
setTimeout(() => { setTimeout(() => {
copyMessage.style.display = 'none'; copyMessage.style.display = 'none';
}, 3000); }, 3000);
isCopyModeEnabled = false; isCopyModeEnabled = false;
if (previousHighlight) { if (previousHighlight) {
previousHighlight.style.background = ''; previousHighlight.style.background = '';
previousHighlight.style.backgroundImage = ''; previousHighlight.style.backgroundImage = '';
previousHighlight.style.border = ''; previousHighlight.style.border = '';
copyButton.style.display = 'none'; copyButton.style.display = 'none';
previousHighlight = null; previousHighlight = null;
} }
console.log('Copy mode disabled'); console.log('Copy mode disabled');
}); });
} }
}); });
copyButton = createCopyButton(); copyButton = createCopyButton();
copyMessage = createCopyMessage(); copyMessage = createCopyMessage();
})(); })();
+20 -20
View File
@@ -1,20 +1,20 @@
document.addEventListener('DOMContentLoaded', function () { document.addEventListener('DOMContentLoaded', function () {
const toggleSwitch = document.getElementById('toggleCopyMode'); const toggleSwitch = document.getElementById('toggleCopyMode');
const statusText = document.getElementById('statusText'); const statusText = document.getElementById('statusText');
toggleSwitch.addEventListener('change', function () { toggleSwitch.addEventListener('change', function () {
chrome.runtime.sendMessage({ action: 'toggleCopyMode' }, function (response) { chrome.runtime.sendMessage({ action: 'toggleCopyMode' }, function (response) {
if (response.copyModeEnabled) { if (response.copyModeEnabled) {
statusText.textContent = 'Copy mode enabled'; statusText.textContent = 'Copy mode enabled';
} else { } else {
statusText.textContent = 'Copy mode disabled'; statusText.textContent = 'Copy mode disabled';
} }
}); });
}); });
// Initialize switch state based on current mode // Initialize switch state based on current mode
chrome.runtime.sendMessage({ action: 'getCopyModeStatus' }, function (response) { chrome.runtime.sendMessage({ action: 'getCopyModeStatus' }, function (response) {
toggleSwitch.checked = response.copyModeEnabled; toggleSwitch.checked = response.copyModeEnabled;
statusText.textContent = response.copyModeEnabled ? 'Copy mode enabled' : 'Copy mode disabled'; statusText.textContent = response.copyModeEnabled ? 'Copy mode enabled' : 'Copy mode disabled';
}); });
}); });