mirror of
https://github.com/NaiboWang/EasySpider.git
synced 2025-04-22 09:17:01 +08:00
Multi-Platform Support
This commit is contained in:
parent
43aa4dd224
commit
c216582115
BIN
Extension/EasySpider_mac.crx
Normal file
BIN
Extension/EasySpider_mac.crx
Normal file
Binary file not shown.
28
Extension/EasySpider_mac.pem
Normal file
28
Extension/EasySpider_mac.pem
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDXazUrRLF9mN3X
|
||||||
|
L3xbQi6khT53dE4oQjv7uXhIvsuYIx95hqj7cM7GTGsLsmmWKoErPOSE9QoqbCBA
|
||||||
|
f10YFIrDmm6qYd3KYSlpZWJ9gguTGLtbCV8c8ksPAwwM2jQ99B+tOSq7Ue0r/f6B
|
||||||
|
BBd3ywr1mix+1TX6MS+vJrkNwhPbgSsP4BqOEMPZUvI56g50xK6BX3kyd3gCWX+d
|
||||||
|
YyAaJwByz1/npoIwGo/mUD8YgtS/GToZjDPkoYgaD0ATnfrlWNEwQwx30oFK5vqC
|
||||||
|
GUFzaKpX6siqK4cX7KhRKK9UknCHhqu4jMbb+fD35ztr3cpdAd1Cw2rUYi04K6l3
|
||||||
|
irsVIMhzAgMBAAECggEABA3kplBSSnImDAjWhfUJNxfLSjWnIKZgVxiG0Psk9MsF
|
||||||
|
xCAxC+onGqQeJiwbmms2LCMNSIKmpgdHqqV9IzbZoEMkpB8Czwf51lEBMtTHLEGW
|
||||||
|
Iz6nAhygFK5qKpxslZ3H5V+tftddQVHev8nc01dzGvyyeI2OQFh/xZ1bhch3IpwO
|
||||||
|
7X/taYUaU/wiTlUEQgfuJBy7bHMS7JxrQQ2gaoh1iwMJruiUZWt41mr5hUxXwVTn
|
||||||
|
BcT+yMMuy36K1B+M6ia983SYUVVBO7iqcY4/nNIUIxQ2MB2v1Bc5E5ZKvO2GA0HR
|
||||||
|
TAqBRApEjMURLvwz83EZ0DzABknr70IfixNgXdeNXQKBgQDvhLhDk5sMrVNN1iV3
|
||||||
|
2Q2P8eUgmHHfzmDihpChD5DP8tNxi4J506DMkaBP4OnmcN5chpZW2oLO8SS6aqCS
|
||||||
|
XZUiTaypWhUu0ukHDlv4nsqJHRccIWDlSqUtLbUN+6JudtLxMrwqylsZjLA6G3Du
|
||||||
|
d4GJnIs+/BaB1c2zAj2fXcyplwKBgQDmPfTAi8+4ZiJvu/VdY/Z0sS7MDxvQmQE6
|
||||||
|
MKjOQEc8Njl8F/fRA7Sz0ms/dkAtkoXeunQgS3T4LxRd0w7OmnlE0Dk3X1vkF10N
|
||||||
|
FIYP1GXrhkLtkzO0rELU7gVVJP7eAP25GWWaG8bN0nmI6r30lC3Xb6QiHBCtv2EY
|
||||||
|
rv1C+xxbhQKBgQDk3020RTfDxVv05Myo2R+8jMkFfKZT1kF+NFe/j8Aw9ThXJ5hm
|
||||||
|
EXN2BzHJIoJfUTsp7vF5zRNx67vM5lbJheMcBF0Y9puHQsKpm28HA7VFkCalGsAc
|
||||||
|
Wle79BEua2WraJ/pGzHzMaobn/RFkjM3q7p8ZLoqVXisWEFW7K01u8v1wQKBgQDY
|
||||||
|
koK880ZKv9e4nmaomDTlgxzv2W5igunCoK7Ig3H+U0szTSBQPVomo9E5+rNXqrG9
|
||||||
|
1kkRb6jxIufXcYZGFMvpTKvlSA+Zt9hRS3LnRPUx3DLsYkCKvFaJD/N4KbqLfQcs
|
||||||
|
q5UEpwgT5t1nStevTgro0Rzk8N1HcfOVUlTsQmRkOQKBgHsFyWCSYYixyWBX+aaq
|
||||||
|
jxtIxfVIHo68z6sV6ERG5KtfXipKpem8ju0sNRzFi1/HwoEX9W6A0S1caeLTqWGt
|
||||||
|
o8kEHyGOOqmJYJaTK20EckDEUUGGpjZ/Wa2MCGNGvTJxQIv4i/g4fNIpWTTy1vRD
|
||||||
|
TQlffAYcH4lGhmlIWFKo+SvY
|
||||||
|
-----END PRIVATE KEY-----
|
18
Extension/EasySpider_mac/_locales/en/messages.json
Normal file
18
Extension/EasySpider_mac/_locales/en/messages.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"appName": {
|
||||||
|
"message": "EasySpider",
|
||||||
|
"description": "The name of the application"
|
||||||
|
},
|
||||||
|
"appShortName": {
|
||||||
|
"message": "es",
|
||||||
|
"description": "The short_name (maximum of 12 characters recommended) is a short version of the app's name."
|
||||||
|
},
|
||||||
|
"appDescription": {
|
||||||
|
"message": "EasySpider",
|
||||||
|
"description": "The description of the application"
|
||||||
|
},
|
||||||
|
"browserActionTitle": {
|
||||||
|
"message": "EasySpider",
|
||||||
|
"description": "The title of the browser action button"
|
||||||
|
}
|
||||||
|
}
|
BIN
Extension/EasySpider_mac/images/api_thumb_450.jpg
Normal file
BIN
Extension/EasySpider_mac/images/api_thumb_450.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
BIN
Extension/EasySpider_mac/images/icon-128.png
Normal file
BIN
Extension/EasySpider_mac/images/icon-128.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 19 KiB |
BIN
Extension/EasySpider_mac/images/icon-16.png
Normal file
BIN
Extension/EasySpider_mac/images/icon-16.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.6 KiB |
BIN
Extension/EasySpider_mac/images/icon-19.png
Normal file
BIN
Extension/EasySpider_mac/images/icon-19.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.9 KiB |
BIN
Extension/EasySpider_mac/images/icon-38.png
Normal file
BIN
Extension/EasySpider_mac/images/icon-38.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.8 KiB |
78
Extension/EasySpider_mac/manifest.json
Normal file
78
Extension/EasySpider_mac/manifest.json
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
{
|
||||||
|
"name": "__MSG_appName__",
|
||||||
|
"short_name": "__MSG_appShortName__",
|
||||||
|
"description": "__MSG_appDescription__",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"manifest_version": 2,
|
||||||
|
"default_locale": "en",
|
||||||
|
"icons": {
|
||||||
|
"16": "images/icon-16.png",
|
||||||
|
"128": "images/icon-128.png"
|
||||||
|
},
|
||||||
|
"background": {
|
||||||
|
"scripts": [
|
||||||
|
"scripts/background.js"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"page_action": {
|
||||||
|
"default_icon": {
|
||||||
|
"19": "images/icon-19.png",
|
||||||
|
"38": "images/icon-38.png"
|
||||||
|
},
|
||||||
|
"default_title": "__MSG_browserActionTitle__",
|
||||||
|
"default_popup": "pages/popup.html"
|
||||||
|
},
|
||||||
|
"options_page": "pages/options.html",
|
||||||
|
"options_ui": {
|
||||||
|
"page": "pages/options.html",
|
||||||
|
"chrome_style": true
|
||||||
|
},
|
||||||
|
"minimum_chrome_version": "10.0",
|
||||||
|
"devtools_page": "pages/devtools.html",
|
||||||
|
"omnibox": {
|
||||||
|
"keyword": "fwbz"
|
||||||
|
},
|
||||||
|
"content_scripts": [{
|
||||||
|
"matches": [
|
||||||
|
"http://*/*",
|
||||||
|
"https://*/*"
|
||||||
|
],
|
||||||
|
"css": [
|
||||||
|
"styles/contentscript.css"
|
||||||
|
],
|
||||||
|
"js": [
|
||||||
|
"scripts/jquery-3.4.1.min.js", "scripts/vue.js", "scripts/baozhuangscript.js", "scripts/contentscript.js", "scripts/messageInteraction.js"
|
||||||
|
],
|
||||||
|
"run_at": "document_end",
|
||||||
|
"all_frames": false
|
||||||
|
}],
|
||||||
|
"web_accessible_resources": ["js/inject.js"],
|
||||||
|
"permissions": [
|
||||||
|
"activeTab",
|
||||||
|
"alarms",
|
||||||
|
"bookmarks",
|
||||||
|
"browsingData",
|
||||||
|
"contextMenus",
|
||||||
|
"cookies",
|
||||||
|
"downloads",
|
||||||
|
"downloads.open",
|
||||||
|
"geolocation",
|
||||||
|
"history",
|
||||||
|
"identity",
|
||||||
|
"idle",
|
||||||
|
"management",
|
||||||
|
"nativeMessaging",
|
||||||
|
"notifications",
|
||||||
|
"privacy",
|
||||||
|
"proxy",
|
||||||
|
"sessions",
|
||||||
|
"storage",
|
||||||
|
"tabs",
|
||||||
|
"topSites",
|
||||||
|
"webNavigation",
|
||||||
|
"webRequest",
|
||||||
|
"webRequestBlocking",
|
||||||
|
"unlimitedStorage",
|
||||||
|
"<all_urls>"
|
||||||
|
]
|
||||||
|
}
|
78
Extension/EasySpider_mac/manifest.json.bak
Normal file
78
Extension/EasySpider_mac/manifest.json.bak
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
{
|
||||||
|
"name": "__MSG_appName__",
|
||||||
|
"short_name": "__MSG_appShortName__",
|
||||||
|
"description": "__MSG_appDescription__",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"manifest_version": 3,
|
||||||
|
"default_locale": "en",
|
||||||
|
"icons": {
|
||||||
|
"16": "images/icon-16.png",
|
||||||
|
"128": "images/icon-128.png"
|
||||||
|
},
|
||||||
|
"background": {
|
||||||
|
"service_worker": "scripts/background.js"
|
||||||
|
},
|
||||||
|
"action": {
|
||||||
|
"default_icon": {
|
||||||
|
"19": "images/icon-19.png",
|
||||||
|
"38": "images/icon-38.png"
|
||||||
|
},
|
||||||
|
"default_title": "__MSG_browserActionTitle__",
|
||||||
|
"default_popup": "pages/popup.html"
|
||||||
|
},
|
||||||
|
"options_page": "pages/options.html",
|
||||||
|
"options_ui": {
|
||||||
|
"page": "pages/options.html"
|
||||||
|
},
|
||||||
|
"minimum_chrome_version": "10.0",
|
||||||
|
"devtools_page": "pages/devtools.html",
|
||||||
|
"omnibox": {
|
||||||
|
"keyword": "fwbz"
|
||||||
|
},
|
||||||
|
"content_scripts": [{
|
||||||
|
"matches": [
|
||||||
|
"http://*/*",
|
||||||
|
"https://*/*"
|
||||||
|
],
|
||||||
|
"css": [
|
||||||
|
"styles/contentscript.css"
|
||||||
|
],
|
||||||
|
"js": [
|
||||||
|
"scripts/jquery-3.4.1.min.js", "scripts/vue.js", "scripts/baozhuangscript.js", "scripts/contentscript.js", "scripts/messageInteraction.js"
|
||||||
|
],
|
||||||
|
"run_at": "document_end",
|
||||||
|
"all_frames": false
|
||||||
|
}],
|
||||||
|
"web_accessible_resources": [{
|
||||||
|
"resources": ["js/inject.js"],
|
||||||
|
"matches": [],
|
||||||
|
"extension_ids": []
|
||||||
|
}],
|
||||||
|
"host_permissions": ["*://*/*"],
|
||||||
|
"permissions": [
|
||||||
|
"activeTab",
|
||||||
|
"alarms",
|
||||||
|
"bookmarks",
|
||||||
|
"browsingData",
|
||||||
|
"contextMenus",
|
||||||
|
"cookies",
|
||||||
|
"downloads",
|
||||||
|
"downloads.open",
|
||||||
|
"geolocation",
|
||||||
|
"history",
|
||||||
|
"identity",
|
||||||
|
"idle",
|
||||||
|
"management",
|
||||||
|
"nativeMessaging",
|
||||||
|
"notifications",
|
||||||
|
"privacy",
|
||||||
|
"proxy",
|
||||||
|
"sessions",
|
||||||
|
"storage",
|
||||||
|
"tabs",
|
||||||
|
"topSites",
|
||||||
|
"webNavigation",
|
||||||
|
"webRequest",
|
||||||
|
"unlimitedStorage"
|
||||||
|
]
|
||||||
|
}
|
14
Extension/EasySpider_mac/pages/devtools.html
Normal file
14
Extension/EasySpider_mac/pages/devtools.html
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<title>Devtools</title>
|
||||||
|
<link rel="stylesheet" type="text/css" href="../styles/devtools.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h1>Devtools</h1>
|
||||||
|
|
||||||
|
<script src="../scripts/popup.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
17
Extension/EasySpider_mac/pages/options.html
Normal file
17
Extension/EasySpider_mac/pages/options.html
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<title>Options</title>
|
||||||
|
<link rel="stylesheet" type="text/css" href="../styles/options.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" name="examplOption" checked>
|
||||||
|
Example Option
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<script src="../scripts/options.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
15
Extension/EasySpider_mac/pages/popup.html
Normal file
15
Extension/EasySpider_mac/pages/popup.html
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<title>Popup</title>
|
||||||
|
<link rel="stylesheet" type="text/css" href="../styles/popup.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h1>Visual Web Crawler</h1>
|
||||||
|
|
||||||
|
<script src="../scripts/popup.js"></script>
|
||||||
|
<script src="../scripts/baozhuangscript.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
68
Extension/EasySpider_mac/scripts/background.js
Normal file
68
Extension/EasySpider_mac/scripts/background.js
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
//此变量用于监听是否加载了新的页面(包括新窗口打开),如果是,增加变量值,用于传回后台。
|
||||||
|
var tabList = []; //用来记录打开的新的tab的id
|
||||||
|
var nowTabId = null;
|
||||||
|
var nowTabIndex = 0; //重要变量!!
|
||||||
|
const extension = {
|
||||||
|
ws: null,
|
||||||
|
};
|
||||||
|
chrome.storage.local.set({ "parameterNum": 1 }); //修改默认的参数索引值
|
||||||
|
// chrome.tabs.update(6,{"active":true}) //一行就可以切换标签页
|
||||||
|
chrome.tabs.onActivated.addListener(function(activeInfo) {
|
||||||
|
nowTabId = activeInfo.tabId; //记录现在活动的tabid
|
||||||
|
if (tabList.indexOf(nowTabId) != -1) {
|
||||||
|
nowTabIndex = tabList.indexOf(nowTabId);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
// 监听来自content-script的消息
|
||||||
|
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
|
||||||
|
if (request.type == 0) {
|
||||||
|
if (tabList.indexOf(sender["tab"]["id"]) < 0) { //元素不存在加入数组
|
||||||
|
tabList.push(sender["tab"]["id"]);
|
||||||
|
}
|
||||||
|
nowTabIndex = tabList.indexOf(nowTabId);
|
||||||
|
sendResponse({ type: 0, "msg": "Get!" }); //回传一个消息
|
||||||
|
} else if (request.type == 1) { //前台询问参数索引值
|
||||||
|
sendResponse({ type: 1, "value": parameterNum }); //回传一个消息
|
||||||
|
} else if (request.type == 2) {
|
||||||
|
let message = {
|
||||||
|
type: 2, //消息类型,2代表键盘输入
|
||||||
|
message: { "keyboardStr": "{}{BS}" + request.msg } // {}全选{BS}退格
|
||||||
|
};
|
||||||
|
extension.ws.send(JSON.stringify(message));
|
||||||
|
} else if (request.type == 3) {
|
||||||
|
let tmsg = request.msg;
|
||||||
|
tmsg.tabIndex = nowTabIndex; //赋值当前tab的id
|
||||||
|
let message = {
|
||||||
|
type: 3, //消息类型,3代表元素增加事件
|
||||||
|
from: 0, //0代表从浏览器到流程图,1代表从流程图到浏览器
|
||||||
|
message: { "pipe": JSON.stringify(request.msg) } // {}全选{BS}退格
|
||||||
|
};
|
||||||
|
console.log(message);
|
||||||
|
extension.ws.send(JSON.stringify(message));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 打开一个 web socket
|
||||||
|
extension.ws = new WebSocket("ws://localhost:8084");
|
||||||
|
extension.ws.onopen = function() {
|
||||||
|
// Web Socket 已连接上,使用 send() 方法发送数据
|
||||||
|
console.log("已连接");
|
||||||
|
message = {
|
||||||
|
type: 0, //消息类型,0代表链接操作
|
||||||
|
message: {
|
||||||
|
id: 0, //socket id
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this.send(JSON.stringify(message));
|
||||||
|
};
|
||||||
|
extension.ws.onmessage = function(evt) {
|
||||||
|
evt = JSON.parse(evt.data);
|
||||||
|
if (evt["type"] == "0") { //0代表更新参数添加索引值
|
||||||
|
chrome.storage.local.set({ "parameterNum": parseInt(evt["value"]) }); //修改值
|
||||||
|
}
|
||||||
|
};
|
||||||
|
extension.ws.onclose = function() {
|
||||||
|
// 关闭 websocket
|
||||||
|
console.log("连接已关闭...");
|
||||||
|
};
|
276
Extension/EasySpider_mac/scripts/baozhuangscript.js
Normal file
276
Extension/EasySpider_mac/scripts/baozhuangscript.js
Normal file
@ -0,0 +1,276 @@
|
|||||||
|
//表现层的处理
|
||||||
|
|
||||||
|
if (window.location.href.indexOf("backEndAddressServiceWrapper") >= 0) {
|
||||||
|
throw "serviceGrid"; //如果是服务器网页页面,则不执行工具
|
||||||
|
}
|
||||||
|
|
||||||
|
//返回element相对node节点的xpath,默认的node节点是: /
|
||||||
|
function readXPath(element, type = 1, node = document.body) {
|
||||||
|
try {
|
||||||
|
if (type == 0) //type=0代表默认可通过id生成xpath type=1代表只能从根节点生成xpath, nodeList里必须使用绝对xpath!
|
||||||
|
{
|
||||||
|
if (element.id !== "") { //判断id属性,如果这个元素有id,则显示//*[@id="xPath"] 形式内容
|
||||||
|
return '//*[@id=\"' + element.id + '\"]';
|
||||||
|
}
|
||||||
|
if (element.className != ""){ //如果有class且某个class name只有一个元素,则使用class name生成xpath
|
||||||
|
console.log("class name: " + element.className);
|
||||||
|
names = element.className.split(" ");
|
||||||
|
for (var i = 0; i < names.length; i++) {
|
||||||
|
if (names[i] != "") {
|
||||||
|
// return '//*[@class=\"' + names[i] + '\"]';
|
||||||
|
console.log('//*[@contains(@class, \"' + names[i] + '\")]');
|
||||||
|
elements_of_class = node.getElementsByClassName(names[i]);
|
||||||
|
console.log("Length of elements_of_class: " + elements_of_class.length);
|
||||||
|
if(elements_of_class.length == 1){
|
||||||
|
return '//*[contains(@class, \"' + names[i] + '\")]'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//这里需要需要主要字符串转译问题,可参考js 动态生成html时字符串和变量转译(注意引号的作用)
|
||||||
|
if (element == node) { //递归到body处,结束递归
|
||||||
|
if (node == document.body) {
|
||||||
|
return '/html/' + element.tagName.toLowerCase();
|
||||||
|
} else {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var ix = 1, //在nodelist中的位置,且每次点击初始化
|
||||||
|
siblings = element.parentNode.childNodes; //同级的子元素
|
||||||
|
|
||||||
|
for (var i = 0, l = siblings.length; i < l; i++) {
|
||||||
|
var sibling = siblings[i];
|
||||||
|
//如果这个元素是siblings数组中的元素,则执行递归操作;arguments.callee代表当前函数的名称
|
||||||
|
if (sibling == element) {
|
||||||
|
return readXPath(element.parentNode, type, node) + '/' + element.tagName.toLowerCase() + '[' + (ix) + ']';
|
||||||
|
//如果不符合,判断是否是element元素,并且是否是相同元素,如果是相同的就开始累加
|
||||||
|
} else if (sibling.nodeType == 1 && sibling.tagName == element.tagName) {
|
||||||
|
//注意此处,为了防止多计算了插入的操作台的3个div元素导致定位错误,这里需要屏蔽掉三个元素的索引号
|
||||||
|
if(sibling.id != "wrapperDiv" && sibling.id != "wrapperTdiv" &&sibling.id != "wrapperToolkit"){
|
||||||
|
ix++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
return "/"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//创造div作为选中元素后的样式存在
|
||||||
|
var div = document.createElement('div');
|
||||||
|
div.style.zIndex = -2147483647;
|
||||||
|
div.setAttribute("id", "wrapperDiv");
|
||||||
|
div.style.position = "fixed";
|
||||||
|
div.style.boxSizing = "border-box";
|
||||||
|
div.style.border = "dotted";
|
||||||
|
|
||||||
|
var tdiv = document.createElement('div');
|
||||||
|
tdiv.style.zIndex = 2147483647;
|
||||||
|
tdiv.style.position = "fixed";
|
||||||
|
tdiv.setAttribute("id", "wrapperTdiv");
|
||||||
|
tdiv.classList = "tdiv";
|
||||||
|
tdiv.style.top = "0px";
|
||||||
|
tdiv.style.width = "3000px";
|
||||||
|
tdiv.style.height = "3000px";
|
||||||
|
tdiv.style.pointerEvents = "none";
|
||||||
|
|
||||||
|
var mousemovebind = false; //如果出现元素默认绑定了mousemove事件导致匹配不到元素的时候,开启第二种模式获得元素
|
||||||
|
|
||||||
|
var toolkit = document.createElement("div")
|
||||||
|
toolkit.classList = "tooltips"; //添加样式
|
||||||
|
toolkit.setAttribute("id", "wrapperToolkit");
|
||||||
|
|
||||||
|
var tooltips = false; //标记鼠标是否在提示框上
|
||||||
|
|
||||||
|
var defaultbgColor = 'rgba(221,221,255,0.8)'; //移动到元素的背景颜色
|
||||||
|
var selectedColor = "rgba(151,255,255, 0.6)"; //选中元素的背景颜色
|
||||||
|
var boxShadowColor = "blue 0px 0px 5px"; //待选元素的边框属性
|
||||||
|
|
||||||
|
|
||||||
|
//右键菜单屏蔽
|
||||||
|
document.oncontextmenu = () => false;
|
||||||
|
var nodeList = []; //已被选中的节点列表
|
||||||
|
var readyList = []; //预备选中的list
|
||||||
|
var outputParameters = []; //输出参数列表
|
||||||
|
var outputParameterNodes = []; //输出参数节点列表
|
||||||
|
NowNode = null;
|
||||||
|
var xnode = null;
|
||||||
|
var step = 0; //记录这是第几次点击操作
|
||||||
|
var style = ""; //记录上个元素的颜色
|
||||||
|
document.addEventListener("mousemove", function() {
|
||||||
|
if (mousemovebind) {
|
||||||
|
tdiv.style.pointerEvents = "none";
|
||||||
|
}
|
||||||
|
|
||||||
|
//如果鼠标在元素框内则点击和选中失效
|
||||||
|
var x = event.clientX;
|
||||||
|
var y = event.clientY;
|
||||||
|
var divx1 = toolkit.offsetLeft;
|
||||||
|
var divy1 = toolkit.offsetTop;
|
||||||
|
var divx2 = toolkit.offsetLeft + toolkit.offsetWidth;
|
||||||
|
var divy2 = toolkit.offsetTop + toolkit.offsetHeight;
|
||||||
|
if (x >= divx1 && x <= divx2 && y >= divy1 && y <= divy2) {
|
||||||
|
tooltips = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
oe = document.elementFromPoint(event.x, event.y);
|
||||||
|
if (oe == tdiv) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
tooltips = false;
|
||||||
|
NowNode = oe;
|
||||||
|
te = 0;
|
||||||
|
exist = 0;
|
||||||
|
exist2 = 0;
|
||||||
|
for (o of nodeList) {
|
||||||
|
if (o["node"] == oe) {
|
||||||
|
exist = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (o of nodeList) {
|
||||||
|
if (o["node"] == xnode) {
|
||||||
|
exist2 = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// console.log(oe);
|
||||||
|
if (xnode == null) {
|
||||||
|
xnode = oe;
|
||||||
|
}
|
||||||
|
if (xnode != oe) {
|
||||||
|
if (exist2 == 0) { //如果上个元素不在数组里,改回上个元素的初始颜色
|
||||||
|
try {
|
||||||
|
xnode.style.backgroundColor = style; //上个元素改回原来元素的背景颜色
|
||||||
|
} catch {
|
||||||
|
xnode.style.backgroundColor = ""; //上个元素改回原来元素的背景颜色
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
style = oe.style.backgroundColor;
|
||||||
|
} catch {
|
||||||
|
style = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exist == 1) {
|
||||||
|
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
oe.style.backgroundColor = defaultbgColor; //设置新元素的背景元素
|
||||||
|
} catch {}
|
||||||
|
|
||||||
|
}
|
||||||
|
xnode = oe;
|
||||||
|
div.style.display = "none";
|
||||||
|
}
|
||||||
|
if (mousemovebind) {
|
||||||
|
tdiv.style.pointerEvents = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
//点击没反应时候的替代方案
|
||||||
|
document.onkeydown = function(event) {
|
||||||
|
// console.log("keydown");
|
||||||
|
var e = event || window.event || arguments.callee.caller.arguments[0];
|
||||||
|
if (e && e.keyCode == 118) { // 按 F7
|
||||||
|
addEl();
|
||||||
|
} else if (e && e.keyCode == 119) { //按F8
|
||||||
|
clearEl();
|
||||||
|
} else if (e && e.keyCode == 120) { //按F9
|
||||||
|
NowNode.focus();
|
||||||
|
NowNode.click();
|
||||||
|
// console.log("click",NowNode);
|
||||||
|
} else {
|
||||||
|
return event.keyCode;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//选中元素到列表中
|
||||||
|
function addEl() {
|
||||||
|
// if (tooltips) {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
let exist = false;
|
||||||
|
for (o of nodeList) {
|
||||||
|
if (o["node"] == oe) {
|
||||||
|
exist = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//元素没有被添加过才去添加
|
||||||
|
if (!exist) {
|
||||||
|
step++;
|
||||||
|
exist = false; //判断刚加入的元素是否在readyList中,如果在,则将所有readylist中的元素全部放入list中
|
||||||
|
for (o of readyList) {
|
||||||
|
if (o["node"] == oe) {
|
||||||
|
exist = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (exist) { //存在在readylist就全选中
|
||||||
|
readyToList(step);
|
||||||
|
if (app._data.selectedDescendents) {
|
||||||
|
handleDescendents(); //如果之前有选中子元素,新加入的节点又则这里也需要重新选择子元素
|
||||||
|
}
|
||||||
|
} else //不然只添加一个元素
|
||||||
|
{
|
||||||
|
clearReady(); //readylist清零重新算
|
||||||
|
nodeList.push({ node: NowNode, "step": step, bgColor: style, "boxShadow": NowNode.style.boxShadow == "" || boxShadowColor ? "none" : NowNode.style.boxShadow, xpath: readXPath(NowNode, 1) });
|
||||||
|
NowNode.style.backgroundColor = selectedColor;
|
||||||
|
}
|
||||||
|
handleElement(); //处理新状态
|
||||||
|
|
||||||
|
//将虚线框显示在元素上方但屏蔽其鼠标操作
|
||||||
|
var pos = NowNode.getBoundingClientRect();
|
||||||
|
div.style.display = "block";
|
||||||
|
div.style.height = NowNode.offsetHeight + "px";
|
||||||
|
div.style.width = NowNode.offsetWidth + "px";
|
||||||
|
div.style.left = pos.left + "px";
|
||||||
|
div.style.top = pos.top + "px";
|
||||||
|
div.style.zIndex = 2147483645;
|
||||||
|
div.style.pointerEvents = "none";
|
||||||
|
}
|
||||||
|
// console.log("------");
|
||||||
|
// for (i = 0; i < nodeList.length; i++) {
|
||||||
|
// console.log(nodeList[i]["xpath"]);
|
||||||
|
// }
|
||||||
|
//对于可点击元素,屏蔽a标签默认点击事件
|
||||||
|
event.stopImmediatePropagation();
|
||||||
|
event.stopPropagation();
|
||||||
|
event.preventDefault ? event.preventDefault() : event.returnValue = false;
|
||||||
|
}
|
||||||
|
document.addEventListener("mousedown", addEl);
|
||||||
|
toolkit.addEventListener("mousedown", function(e) { e.stopPropagation(); }); //重新定义toolkit里的点击事件
|
||||||
|
//清除选择项
|
||||||
|
function clearEl() {
|
||||||
|
//如果最后停留的元素被选中,则调整此元素的style为原始style,否则不进行调整
|
||||||
|
for (node of nodeList) {
|
||||||
|
node["node"].style.backgroundColor = node["bgColor"];
|
||||||
|
node["node"].style.boxShadow = node["boxShadow"];
|
||||||
|
if (NowNode == node["node"]) {
|
||||||
|
style = node["bgColor"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
step = 0;
|
||||||
|
clearReady();
|
||||||
|
clearParameters();
|
||||||
|
nodeList.splice(0, nodeList.length); //清空数组
|
||||||
|
app._data.option = 0; //选项重置
|
||||||
|
app._data.page = 0; //恢复原始页面
|
||||||
|
}
|
||||||
|
|
||||||
|
//清除预备数组
|
||||||
|
function clearReady() {
|
||||||
|
for (node of readyList) //节点列表状态恢复原状
|
||||||
|
{
|
||||||
|
node["node"].style.boxShadow = node["boxShadow"];
|
||||||
|
}
|
||||||
|
readyList.splice(0, readyList.length); //清空数组
|
||||||
|
}
|
||||||
|
document.body.append(div); //默认如果toolkit不存在则div和tdiv也不存在
|
||||||
|
document.body.append(tdiv);
|
||||||
|
document.body.append(toolkit);
|
||||||
|
var timer;
|
933
Extension/EasySpider_mac/scripts/contentscript.js
Normal file
933
Extension/EasySpider_mac/scripts/contentscript.js
Normal file
@ -0,0 +1,933 @@
|
|||||||
|
//表现逻辑层的处理
|
||||||
|
|
||||||
|
if (window.location.href.indexOf("backEndAddressServiceWrapper") >= 0) {
|
||||||
|
throw "serviceGrid"; //如果是服务器网页页面, 则不执行工具
|
||||||
|
}
|
||||||
|
|
||||||
|
//Vueelement
|
||||||
|
var app;
|
||||||
|
generateToolkit();
|
||||||
|
//生成Toolkit
|
||||||
|
function generateToolkit() {
|
||||||
|
$(".tooltips").html(`
|
||||||
|
<div id="realcontent">
|
||||||
|
<div class="tooldrag">✍Operation Toolbox (Can drag)</div>
|
||||||
|
<div class="realcontent">
|
||||||
|
<div v-if="page==0">
|
||||||
|
<input type="checkbox" style="width:15px;height:15px;vertical-align:middle;" v-on:mousedown="specialSelect"> </input>
|
||||||
|
<p style="margin-bottom:10px;display:inline-block">Special click mode</p>
|
||||||
|
<div v-if="list.nl.length==0">
|
||||||
|
<p style="color:black">● When your mouse moves to the element, please <strong>right-click</strong> your mouse button or press <strong>F7</strong> on the keyboard to select it.</p>
|
||||||
|
<p style="color:black">● You can click the back button to go back to the page</p>
|
||||||
|
{{initial()}}
|
||||||
|
</div>
|
||||||
|
<div v-if="list.nl.length==1">
|
||||||
|
<div v-if="tname()!='null'">
|
||||||
|
● Already selected {{numOfList()}} {{tname()}}, <span v-if="numOfReady()>0&&tname()!='Elements in next page'"> meanwhile we find {{numOfReady()}} element with the same type, </span>you can:
|
||||||
|
<div class="innercontent">
|
||||||
|
<div v-if="numOfReady()>0 && !selectStatus"> <a v-on:mousedown="selectAll">Select All</a><span title="">☺</span></div>
|
||||||
|
<div v-if="existDescendents()&& !selectStatus &&(tname()=='element' || tname()=='link')"> <a v-on:mousedown="selectDescendents">Select child elements</a> <span title="">☺</span></div>
|
||||||
|
<div v-if="!selectedDescendents && !selectStatus" id="Single">
|
||||||
|
<!-- <div v-if="tname()=='selection box'"> <a>循环切换该下拉项</a><span title="">☺</span></div> -->
|
||||||
|
<div v-if="tname()=='text box'"> <a v-on:mousedown="setInput">Input Text</a><span title="">☺</span></div>
|
||||||
|
<div v-if="tname()!='Image'"> <a v-on:mousedown="getText">Extract {{tname()}}'s text</a><span title="collet text">☺</span></div>
|
||||||
|
<div v-if="tname()=='selection box'"> <a>Collect text from this element</a><span title="">☺</span></div>
|
||||||
|
<div v-if="tname()=='link'||tname()=='Image'"> <a v-on:mousedown="getLink">Collect address of this {{tname()}}</a><span title="">☺</span></div>
|
||||||
|
<div v-if="tname()!='selection box' && tname()!='text box'"> <a v-on:mousedown="clickElement">Click this {{tname()}}</a><span title="">☺</span></div>
|
||||||
|
<div v-if="tname()!='selection box' && tname()!='text box'"> <a v-on:mousedown="loopClickSingleElement">Loop-click this {{tname()}}</a><span title="">☺</span></div>
|
||||||
|
<div v-if="tname()=='link'||tname()=='element'"> <a v-on:mousedown="getInnerHtml">Collect Inner Html of this {{tname()}}</a><span title="">☺</span></div>
|
||||||
|
<div> <a v-on:mousedown="getOuterHtml">Collect Outer Html of this element</a><span title="">☺</span></div>
|
||||||
|
<!-- <div> <a href="#">鼠标移动到该元素上----{{tname()}}-</a><span title="">☺</span></div> -->
|
||||||
|
<!-- <div v-if="tname()=='text box'"> <a>识别验证码</a><span title="">☺</span></div> -->
|
||||||
|
</div>
|
||||||
|
<div v-if="selectedDescendents" id="Single">
|
||||||
|
<div><a v-on:mousedown="confirmCollectSingle">Collect Data</a><span title="">☺</span></div>
|
||||||
|
</div>
|
||||||
|
<div v-if="selectStatus" id="Confirm">
|
||||||
|
<div><a v-on:mousedown="confirmCollectSingle">Confirm Collect</a><span title="">☺</span></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="list.nl.length>1">
|
||||||
|
|
||||||
|
<div v-if="option==100">
|
||||||
|
● Already selected the follwoing element, you can:
|
||||||
|
<div class="innercontent">
|
||||||
|
<div> <a v-on:mousedown="confirmCollectMulti">Collect Data</a><span title="">☺</span> </div>
|
||||||
|
<div> <a v-on:mousedown="revoke">Revoke selection</a><span title="">☺</span></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="option!=100">
|
||||||
|
● Already selected {{numOfList()}} similar elements, <span v-if="numOfReady()>0">and we find other{{numOfReady()}} similar elements, </span>you can:
|
||||||
|
<div class="innercontent">
|
||||||
|
<div v-if="numOfReady()>0"> <a v-on:mousedown="selectAll">Select All</a><span title="">☺</span></div>
|
||||||
|
<div v-if="existDescendents()&&(tname()=='element' || tname()=='link')"> <a v-on:mousedown="selectDescendents">Select child elements</a><span title="">☺</span></div>
|
||||||
|
<div> <a v-on:mousedown="confirmCollectMultiAndDescendents">Collect Data</a><span title="">☺</span></div>
|
||||||
|
<div v-if="tname()!='selection box' && tname()!='text box' && !selectedDescendents"> <a v-on:mousedown="loopClickEveryElement">Loop-click every {{tname()}}</a><span title="">☺</span></div>
|
||||||
|
<div> <a v-on:mousedown="revoke">Revoke selection</a><span title="">☺</span></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="valTable.length>0">
|
||||||
|
<div class="toolkitcontain">{{setWidth("350px")}}
|
||||||
|
<table class="toolkittb2" cellspacing="0">
|
||||||
|
<tbody>
|
||||||
|
<th v-for="i in list.opp">{{i["name"]}}</th>
|
||||||
|
<th style="width:40px">Delete</td>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<table class="toolkittb4" cellspacing="0">
|
||||||
|
<tbody>
|
||||||
|
<tr v-for="i in valTable[0].length">
|
||||||
|
<td v-for="j in list.opp.length">{{valTable[j-1][i-1]}}</td>
|
||||||
|
<td v-on:mousedown="deleteSingleLine" style="font-size: 22px!important;width:40px;cursor:pointer" v-bind:index="i-1">×</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="valTable.length==0&&tname()!='Elements in next page'">{{setWidth("290px")}}</div>
|
||||||
|
|
||||||
|
<div v-if="list.nl.length>0" style="bottom:12px;position:absolute;color:black!important;left:17px;font-size:13px">
|
||||||
|
<div style="margin-bottom:5px">
|
||||||
|
<button v-on:mousedown="cancel">Deselect</button>
|
||||||
|
<button v-if="!selectStatus" v-on:mousedown="enlarge">Expand Path</button>
|
||||||
|
</div>
|
||||||
|
<p style="margin-left:16px;margin-bottom:0px">{{lastElementXPath()}}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="page==1">
|
||||||
|
● Please input text:
|
||||||
|
<input type="text" v-model="text" autofocus="autofocus" id="WTextBox"></input>
|
||||||
|
<button v-on:click="getInput" style="margin-left:0px!important;">Confirm</button>
|
||||||
|
<button v-on:click="cancelInput" style="margin-left:0px!important;">Cancel</button>
|
||||||
|
<div class="innercontent">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`);
|
||||||
|
app = new Vue({
|
||||||
|
el: '#realcontent',
|
||||||
|
data: {
|
||||||
|
option: 0,
|
||||||
|
list: { nl: nodeList, opp: outputParameters },
|
||||||
|
valTable: [], // 用来存储转换后的para列表
|
||||||
|
special: false, //是否为特殊selection模式
|
||||||
|
selectedDescendents: false, // 标记是否选中了子element
|
||||||
|
selectStatus: false, //标记单个element是否点击了采集
|
||||||
|
page: 0, //默认页面, 1为输入文字页面
|
||||||
|
text: "", // 记录输入的文字
|
||||||
|
tNodeName: "", // 记录临时节点列表
|
||||||
|
nowPath: "", //现在element的xpath
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
nowPath: { //变量发生变化的时候进行一些操作
|
||||||
|
handler: function(newVal, oldVal) {
|
||||||
|
console.log("xpath:", newVal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
initial: function() { //每当element是0的时候, 执行值的初始化操作
|
||||||
|
this.selectedDescendents = false;
|
||||||
|
this.selectStatus = false;
|
||||||
|
this.nowPath = "";
|
||||||
|
},
|
||||||
|
confirmCollectSingle: function() { //单element确认采集
|
||||||
|
collectSingle();
|
||||||
|
clearEl();
|
||||||
|
},
|
||||||
|
confirmCollectMulti: function() { //无规律多element确认采集
|
||||||
|
collectMultiNoPattern();
|
||||||
|
clearEl();
|
||||||
|
},
|
||||||
|
confirmCollectMultiAndDescendents: function() { //有规律多element确认采集
|
||||||
|
collectMultiWithPattern();
|
||||||
|
clearEl();
|
||||||
|
},
|
||||||
|
deleteSingleLine: function(event) { //删除单行element
|
||||||
|
let at = new Date().getTime()
|
||||||
|
//流程图送element的时候, 默认的使用不固定循环列表, 但是一旦有删除element的操作发生, 则按照固定element列表采集element
|
||||||
|
index = event.target.getAttribute("index");
|
||||||
|
let tnode = nodeList.splice(index, 1)[0]; //删掉当前element
|
||||||
|
tnode["node"].style.backgroundColor = tnode["bgColor"];
|
||||||
|
tnode["node"].style.boxShadow = tnode["boxShadow"];
|
||||||
|
if (nodeList.length > 1) { // 如果删到没有就没有其他的操作了
|
||||||
|
handleElement();
|
||||||
|
if (this.selectedDescendents) {
|
||||||
|
handleDescendents(); //如果之前有Select child elements, 新加入的节点又则这里也需要重新selection子element
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.valTable = [];
|
||||||
|
this.selectStatus = false;
|
||||||
|
clearParameters(); //直接Revoke 重选
|
||||||
|
}
|
||||||
|
let at2 = parseInt(new Date().getTime());
|
||||||
|
console.log("delete:", at2, at, at2 - at);
|
||||||
|
},
|
||||||
|
clickElement: function() { //点击element操作
|
||||||
|
sendSingleClick();
|
||||||
|
//先发送数据
|
||||||
|
nodeList[0]["node"].focus(); //获得element焦点
|
||||||
|
nodeList[0]["node"].click(); //点击element
|
||||||
|
clearEl();
|
||||||
|
},
|
||||||
|
loopClickSingleElement: function() { //循环点击单个element
|
||||||
|
sendLoopClickSingle(this.tname()); //识别下一页,循环点击单个element和点击多个element
|
||||||
|
if (this.tname() != "Elements in next page") { //Elements in next page不进行点击操作
|
||||||
|
nodeList[0]["node"].focus(); //获得element焦点
|
||||||
|
nodeList[0]["node"].click(); //点击element
|
||||||
|
}
|
||||||
|
clearEl();
|
||||||
|
},
|
||||||
|
loopClickEveryElement: function() { //循环点击每个element
|
||||||
|
sendLoopClickEvery(); //识别下一页,循环点击单个element和点击多个element
|
||||||
|
nodeList[0]["node"].focus(); //获得element焦点
|
||||||
|
nodeList[0]["node"].click(); //点击element
|
||||||
|
clearEl();
|
||||||
|
},
|
||||||
|
setInput: function() { //输入文字
|
||||||
|
this.page = 1;
|
||||||
|
this.$nextTick(function() { //下一时刻获得焦点
|
||||||
|
document.getElementById("WTextBox").focus();
|
||||||
|
})
|
||||||
|
},
|
||||||
|
getInput: function() { //得到输入的文字
|
||||||
|
nodeList[0]["node"].focus(); //获得文字焦点
|
||||||
|
nodeList[0]["node"].setAttribute("value", this.text); // 设置输入 box内容
|
||||||
|
input(this.text); // 设置输入
|
||||||
|
this.text = "";
|
||||||
|
clearEl();
|
||||||
|
},
|
||||||
|
cancelInput: function() {
|
||||||
|
this.page = 0;
|
||||||
|
},
|
||||||
|
setWidth: function(width) { //根据是否出现表格调整最外 box宽度
|
||||||
|
$(".tooltips").css("width", width);
|
||||||
|
return "";
|
||||||
|
},
|
||||||
|
getText: function() { //采集文字
|
||||||
|
generateParameters(0, true, false);
|
||||||
|
this.selectStatus = true;
|
||||||
|
clearReady();
|
||||||
|
},
|
||||||
|
getLink: function() { //采集linkAddress
|
||||||
|
generateParameters(0, false, true);
|
||||||
|
this.selectStatus = true;
|
||||||
|
clearReady();
|
||||||
|
},
|
||||||
|
getOuterHtml: function() { //采集OuterHtml
|
||||||
|
generateParameters(3, true, false);
|
||||||
|
this.selectStatus = true;
|
||||||
|
clearReady();
|
||||||
|
},
|
||||||
|
getInnerHtml: function() { //采集InnerHtml
|
||||||
|
generateParameters(2, true, false);
|
||||||
|
this.selectStatus = true;
|
||||||
|
clearReady();
|
||||||
|
},
|
||||||
|
tname: function() {
|
||||||
|
let tag = nodeList.length == 0 ? "" : nodeList[0]["node"].tagName;
|
||||||
|
let inputType = nodeList.length == 0 ? "" : nodeList[0]["node"].getAttribute("type");
|
||||||
|
if (inputType != null) { //如果没有type属性, 则默认为text
|
||||||
|
inputType = inputType.toLowerCase();
|
||||||
|
} else {
|
||||||
|
inputType = "text";
|
||||||
|
}
|
||||||
|
if (tag == "") {
|
||||||
|
return "null";
|
||||||
|
} else if ($(nodeList[0]["node"]).contents().filter(function() { return this.nodeType === 3; }).text().indexOf("Next") >= 0) {
|
||||||
|
this.setWidth("310px");
|
||||||
|
return "Elements in next page";
|
||||||
|
} else if (tag == "A") {
|
||||||
|
return "link";
|
||||||
|
} else if (tag == "IMG") {
|
||||||
|
return "Image";
|
||||||
|
} else if (tag == "BUTTON" || (tag == "INPUT" && (inputType == "button" || inputType == "submit"))) {
|
||||||
|
return "Button";
|
||||||
|
} else if (tag == "TEXTAREA" || (tag == "INPUT" && (inputType != "checkbox" || inputType != "ratio"))) { //普通输入 box
|
||||||
|
return "text box";
|
||||||
|
} else if (tag == "SELECT") {
|
||||||
|
return "selection box";
|
||||||
|
} else {
|
||||||
|
return "element";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
existDescendents: function() { //检测选中的element是否存在子element,Already 经选中了子element也不要再出现了
|
||||||
|
return nodeList.length > 0 && nodeList[0]["node"].children.length > 0 && !this.selectedDescendents;
|
||||||
|
},
|
||||||
|
numOfReady: function() {
|
||||||
|
return readyList.length;
|
||||||
|
},
|
||||||
|
numOfList: function() {
|
||||||
|
return nodeList.length;
|
||||||
|
},
|
||||||
|
lastElementXPath: function() { //用来显示element的最大最后5个xpath路劲element
|
||||||
|
path = nodeList[nodeList.length - 1]["xpath"];
|
||||||
|
path = path.split("/");
|
||||||
|
tp = "";
|
||||||
|
if (path.length > 5) { //只保留最后五个element
|
||||||
|
path = path.splice(path.length - 5, 5);
|
||||||
|
tp = ".../"
|
||||||
|
}
|
||||||
|
for (i = 0; i < path.length; i++) {
|
||||||
|
path[i] = path[i].split("[")[0];
|
||||||
|
}
|
||||||
|
path = path.join("/");
|
||||||
|
path = "Path: " + tp + path;
|
||||||
|
return path;
|
||||||
|
},
|
||||||
|
cancel: function() {
|
||||||
|
clearEl();
|
||||||
|
},
|
||||||
|
specialSelect: function() { //特殊selection模式
|
||||||
|
if (mousemovebind) {
|
||||||
|
tdiv.style.pointerEvents = "none";
|
||||||
|
this.special = false;
|
||||||
|
} else {
|
||||||
|
this.special = true;
|
||||||
|
}
|
||||||
|
mousemovebind = !mousemovebind;
|
||||||
|
},
|
||||||
|
enlarge: function() { // 扩大选区功能, 总是扩大最后一个选中的element的选区
|
||||||
|
if (nodeList[nodeList.length - 1]["node"].tagName != "BODY") {
|
||||||
|
nodeList[nodeList.length - 1]["node"].style.backgroundColor = nodeList[nodeList.length - 1]["bgColor"]; //之前element恢复原来的背景颜色
|
||||||
|
nodeList[nodeList.length - 1]["node"].style.boxShadow = nodeList[nodeList.length - 1]["boxShadow"]; //之前element恢复原来的背景颜色
|
||||||
|
tNode = nodeList[nodeList.length - 1]["node"].parentNode; //向上走一层
|
||||||
|
if (tNode != NowNode) { //扩大选区之后背景颜色的判断, 当前正好选中的颜色应该是不同的
|
||||||
|
sty = tNode.style.backgroundColor;
|
||||||
|
} else {
|
||||||
|
sty = style;
|
||||||
|
}
|
||||||
|
nodeList[nodeList.length - 1]["node"] = tNode;
|
||||||
|
nodeList[nodeList.length - 1]["bgColor"] = sty;
|
||||||
|
nodeList[nodeList.length - 1]["xpath"] = readXPath(tNode, 1);
|
||||||
|
//显示 box
|
||||||
|
var pos = tNode.getBoundingClientRect();
|
||||||
|
div.style.display = "block";
|
||||||
|
div.style.height = tNode.offsetHeight + "px";
|
||||||
|
div.style.width = tNode.offsetWidth + "px";
|
||||||
|
div.style.left = pos.left + "px";
|
||||||
|
div.style.top = pos.top + "px";
|
||||||
|
div.style.zIndex = 2147483645;
|
||||||
|
div.style.pointerEvents = "none";
|
||||||
|
handleElement(); //每次数组element有变动, 都需要重新处理下
|
||||||
|
oe = tNode;
|
||||||
|
tNode.style.backgroundColor = "rgba(0,191,255,0.5)";
|
||||||
|
this.selectedDescendents = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
selectAll: function() { //Select Allelement
|
||||||
|
step++;
|
||||||
|
readyToList(step, false);
|
||||||
|
handleElement();
|
||||||
|
if (this.selectedDescendents) {
|
||||||
|
handleDescendents(); //如果之前有Select child elements, 新加入的节点又则这里也需要重新selection子element
|
||||||
|
}
|
||||||
|
},
|
||||||
|
revoke: function() { //Revoke selection当前节点
|
||||||
|
var tstep = step;
|
||||||
|
step--; //步数-1
|
||||||
|
while (tstep == nodeList[nodeList.length - 1]["step"]) //删掉所有当前步数的element节点
|
||||||
|
{
|
||||||
|
let node = nodeList.splice(nodeList.length - 1, 1)[0]; //删除数组最后一项
|
||||||
|
node["node"].style.backgroundColor = node["bgColor"]; //还原原始属性和边 box
|
||||||
|
node["node"].style.boxShadow = node["boxShadow"];
|
||||||
|
if (NowNode == node["node"]) {
|
||||||
|
style = node["bgColor"];
|
||||||
|
}
|
||||||
|
//处理Already 经有Select child elements的情况
|
||||||
|
// if (this.selectedDescendents) {
|
||||||
|
clearParameters(); //直接Revoke 重选
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
handleElement(); //每次数组element有变动, 都需要重新处理下
|
||||||
|
},
|
||||||
|
selectDescendents: function() { //selection所有子element操作
|
||||||
|
handleDescendents();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
h = $(".tooldrag").height();
|
||||||
|
difference = 26 - h; //获得高度值差
|
||||||
|
if (difference > 0) {
|
||||||
|
$(".tooldrag").css("cssText", "height:" + (26 + difference) + "px!important")
|
||||||
|
}
|
||||||
|
timer = setInterval(function() { //时刻监测相应element是否存在(防止出现如百度一样element消失重写body的情况), 如果不存在, 添加进来
|
||||||
|
if (document.body != null && document.getElementById("wrapperToolkit") == null) {
|
||||||
|
this.clearInterval(); //先Cancel原来的计时器, 再设置新的计时器
|
||||||
|
document.body.append(div); //默认如果toolkit不存在则div和tdiv也不存在
|
||||||
|
document.body.append(tdiv);
|
||||||
|
document.body.append(toolkit);
|
||||||
|
generateToolkit();
|
||||||
|
// var list = document.getElementsByTagName("a");
|
||||||
|
// // 对于没有特殊绑定函数的a标签, 使他们在新标签页中打开
|
||||||
|
// for (var i = 0; i < list.length; i++) {
|
||||||
|
// if (list[i].href.indexOf("javascript") == -1 && list[i].href.indexOf("void") == -1 && list[i].href.indexOf("#") == -1 && list[i].href) {
|
||||||
|
// list[i].setAttribute("target", "_blank");
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
// list = document.getElementsByTagName("form");
|
||||||
|
// // 对于没有特殊绑定函数的form标签, 使他们在新标签页中打开
|
||||||
|
// for (var i = 0; i < list.length; i++) {
|
||||||
|
// list[i].setAttribute("target", "_blank");
|
||||||
|
// };
|
||||||
|
}
|
||||||
|
}, 3000);
|
||||||
|
}
|
||||||
|
|
||||||
|
//每次对element进行增删之后需要执行的操作
|
||||||
|
function handleElement() {
|
||||||
|
clearReady(); //预备element每次处理都先处理掉
|
||||||
|
if (nodeList.length > 1) { //选中了许多element的情况
|
||||||
|
app._data.option = relatedTest();
|
||||||
|
if (app._data.option == 100) {
|
||||||
|
generateMultiParameters();
|
||||||
|
} else {
|
||||||
|
generateParameters(0);
|
||||||
|
}
|
||||||
|
} else if (nodeList.length == 1) {
|
||||||
|
findRelated(); //寻找和element相关的element
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearParameters(deal = true) //清空para列表
|
||||||
|
{
|
||||||
|
if (deal) //是否Cancel对选中的子element进行处理
|
||||||
|
{
|
||||||
|
app._data.selectedDescendents = false;
|
||||||
|
}
|
||||||
|
for (o of outputParameterNodes) {
|
||||||
|
o["node"].style.boxShadow = o["boxShadow"];
|
||||||
|
}
|
||||||
|
outputParameterNodes.splice(0);
|
||||||
|
outputParameters.splice(0); //清空原来的para列表
|
||||||
|
app._data.valTable = []; //清空展现数组
|
||||||
|
app._data.selectStatus = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//根据nodelist列表内的element生成para列表
|
||||||
|
//适合:nodelist中的element为同类型element
|
||||||
|
//type:0为全部text 1为节点内直接的文字 2为innerhtml 3为outerhtml
|
||||||
|
//nodetype:0,对应全type0123
|
||||||
|
//nodetype:1 link, 对应type0123
|
||||||
|
//nodetype:2 linkAddress 对应type0
|
||||||
|
//nodetype:3 按钮和输入text box 对应type
|
||||||
|
//nodetype:4 按钮和输入text box 对应type
|
||||||
|
|
||||||
|
function generateParameters(type, linktext = true, linkhref = true) {
|
||||||
|
clearParameters(false);
|
||||||
|
let n = 1;
|
||||||
|
chrome.storage.local.get({ parameterNum: 1 }, function(items) {
|
||||||
|
let at = parseInt(new Date().getTime());
|
||||||
|
n = items.parameterNum;
|
||||||
|
for (let num = 0; num < nodeList.length; num++) {
|
||||||
|
let nd = nodeList[num]["node"];
|
||||||
|
ndPath = nodeList[num]["xpath"];
|
||||||
|
outputParameterNodes.push({ "node": nd, "boxShadow": nd.style.boxShadow == "" || boxShadowColor ? "none" : nd.style.boxShadow });
|
||||||
|
nd.style.boxShadow = boxShadowColor;
|
||||||
|
let pname = "text";
|
||||||
|
let ndText = "";
|
||||||
|
if (type == 0) {
|
||||||
|
ndText = $(nd).text();
|
||||||
|
pname = "text";
|
||||||
|
if (nd.tagName == "IMG") {
|
||||||
|
ndText = nd.getAttribute("src") == null ? "" : $(nd).prop("src");
|
||||||
|
pname = "Address";
|
||||||
|
} else if (nd.tagName == "INPUT") {
|
||||||
|
ndText = nd.getAttribute("value") == null ? "" : nd.getAttribute("value");
|
||||||
|
}
|
||||||
|
} else if (type == 1) {
|
||||||
|
ndText = $(nd).contents().filter(function() { return this.nodeType === 3; }).text().replace(/\s+/g, '');
|
||||||
|
pname = "text";
|
||||||
|
if (nd.tagName == "IMG") {
|
||||||
|
ndText = nd.getAttribute("src") == null ? "" : $(nd).prop("src");
|
||||||
|
pname = "Address";
|
||||||
|
} else if (nd.tagName == "INPUT") {
|
||||||
|
ndText = nd.getAttribute("value") == null ? "" : nd.getAttribute("value");
|
||||||
|
}
|
||||||
|
} else if (type == 2) {
|
||||||
|
ndText = $(nd).html();
|
||||||
|
pname = "Innerhtml";
|
||||||
|
} else if (type == 3) {
|
||||||
|
ndText = $(nd).prop("outerHTML");
|
||||||
|
pname = "outerHTML";
|
||||||
|
}
|
||||||
|
if (num == 0) { //第一个节点新建, 后面的增加即可
|
||||||
|
if (nd.tagName == "IMG") { //如果element是Image
|
||||||
|
outputParameters.push({
|
||||||
|
"nodeType": 4, //节点类型
|
||||||
|
"contentType": type, // 内容类型
|
||||||
|
"relative": nodeList.length > 1 ? true : false, //是否为相对xpath路径
|
||||||
|
"name": "para" + (n++) + "_Image" + pname,
|
||||||
|
"desc": "", //para描述
|
||||||
|
"relativeXpath": nodeList.length > 1 ? "" : ndPath,
|
||||||
|
"exampleValues": [{ "num": num, "value": ndText }]
|
||||||
|
});
|
||||||
|
} else if (nd.tagName == "A") { //如果element是超链接
|
||||||
|
if (linktext) {
|
||||||
|
outputParameters.push({
|
||||||
|
"nodeType": 1,
|
||||||
|
"contentType": type, // 内容类型
|
||||||
|
"relative": nodeList.length > 1 ? true : false, //是否为相对xpath路径
|
||||||
|
"name": "para" + (n++) + "_link" + pname,
|
||||||
|
"desc": "", //para描述
|
||||||
|
"relativeXpath": nodeList.length > 1 ? "" : ndPath,
|
||||||
|
"exampleValues": [{ "num": num, "value": ndText }]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (linkhref) {
|
||||||
|
outputParameters.push({
|
||||||
|
"nodeType": 2,
|
||||||
|
"contentType": type, // 内容类型
|
||||||
|
"relative": nodeList.length > 1 ? true : false, //是否为相对xpath路径
|
||||||
|
"name": "para" + (n++) + "_linkAddress",
|
||||||
|
"desc": "", //para描述
|
||||||
|
"relativeXpath": nodeList.length > 1 ? "" : ndPath,
|
||||||
|
"exampleValues": [{ "num": num, "value": nd.getAttribute("href") == null ? "" : $(nd).prop("href") }]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else if (nd.tagName == "INPUT") { //如果element是输入项
|
||||||
|
outputParameters.push({
|
||||||
|
"nodeType": 3,
|
||||||
|
"contentType": type, // 内容类型
|
||||||
|
"relative": nodeList.length > 1 ? true : false, //是否为相对xpath路径
|
||||||
|
"name": "para" + (n++) + "_" + pname,
|
||||||
|
"desc": "", //para描述
|
||||||
|
"relativeXpath": nodeList.length > 1 ? "" : ndPath,
|
||||||
|
"exampleValues": [{ "num": num, "value": ndText }]
|
||||||
|
});
|
||||||
|
} else { //其他所有情况
|
||||||
|
outputParameters.push({
|
||||||
|
"nodeType": 0,
|
||||||
|
"contentType": type, // 内容类型
|
||||||
|
"relative": nodeList.length > 1 ? true : false, //是否为相对xpath路径
|
||||||
|
"name": "para" + (n++) + "_" + pname,
|
||||||
|
"desc": "", //para描述
|
||||||
|
"relativeXpath": nodeList.length > 1 ? "" : ndPath,
|
||||||
|
"exampleValues": [{ "num": num, "value": ndText }]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else { //如果element节点Already 经存在, 则只需要插入值就可以了
|
||||||
|
if (nd.tagName == "IMG") { //如果element是Image
|
||||||
|
outputParameters[0]["exampleValues"].push({ "num": num, "value": ndText });
|
||||||
|
} else if (nd.tagName == "A") { //如果element是超链接
|
||||||
|
outputParameters[0]["exampleValues"].push({ "num": num, "value": ndText });
|
||||||
|
outputParameters[1]["exampleValues"].push({ "num": num, "value": nd.getAttribute("href") == null ? "" : $(nd).prop("href") });
|
||||||
|
} else if (nd.tagName == "INPUT") { //如果element是输入项
|
||||||
|
outputParameters[0]["exampleValues"].push({ "num": num, "value": ndText });
|
||||||
|
} else { //其他所有情况
|
||||||
|
outputParameters[0]["exampleValues"].push({ "num": num, "value": ndText });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let at2 = parseInt(new Date().getTime());
|
||||||
|
console.log("generateParameters:", at2, at, at2 - at);
|
||||||
|
generateValTable();
|
||||||
|
console.log(outputParameters);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//根据nodelist列表内的element生成para列表
|
||||||
|
//适合:nodelist中的element为不同类型element
|
||||||
|
function generateMultiParameters() {
|
||||||
|
clearParameters(false);
|
||||||
|
let n = 1;
|
||||||
|
chrome.storage.local.get({ parameterNum: 1 }, function(items) {
|
||||||
|
let at = parseInt(new Date().getTime());
|
||||||
|
n = items.parameterNum;
|
||||||
|
for (let num = 0; num < nodeList.length; num++) {
|
||||||
|
let nd = nodeList[num]["node"];
|
||||||
|
ndPath = nodeList[num]["xpath"];
|
||||||
|
outputParameterNodes.push({ "node": nd, "boxShadow": nd.style.boxShadow == "" || boxShadowColor ? "none" : nd.style.boxShadow });
|
||||||
|
nd.style.boxShadow = boxShadowColor;
|
||||||
|
ndText = $(nd).text();
|
||||||
|
if (nd.tagName == "IMG") { //如果element是Image
|
||||||
|
outputParameters.push({
|
||||||
|
"nodeType": 4, //节点类型
|
||||||
|
"contentType": 0, // 内容类型
|
||||||
|
"relative": false, //是否为相对xpath路径
|
||||||
|
"name": "para" + (n++) + "_imageAddress",
|
||||||
|
"desc": "", //para描述
|
||||||
|
"relativeXpath": ndPath,
|
||||||
|
"exampleValues": [{ "num": 0, "value": nd.getAttribute("src") == null ? "" : $(nd).prop("src") }]
|
||||||
|
});
|
||||||
|
} else if (nd.tagName == "A") { //如果element是超链接
|
||||||
|
outputParameters.push({
|
||||||
|
"nodeType": 1,
|
||||||
|
"contentType": 0, // 内容类型
|
||||||
|
"relative": false, //是否为相对xpath路径
|
||||||
|
"name": "para" + (n++) + "_linktext",
|
||||||
|
"desc": "", //para描述
|
||||||
|
"relativeXpath": ndPath,
|
||||||
|
"exampleValues": [{ "num": 0, "value": ndText }]
|
||||||
|
});
|
||||||
|
outputParameters.push({
|
||||||
|
"nodeType": 2,
|
||||||
|
"contentType": 0, // 内容类型
|
||||||
|
"relative": false, //是否为相对xpath路径
|
||||||
|
"name": "para" + (n++) + "_linkAddress",
|
||||||
|
"desc": "", //para描述
|
||||||
|
"relativeXpath": ndPath,
|
||||||
|
"exampleValues": [{ "num": 0, "value": nd.getAttribute("href") == null ? "" : $(nd).prop("href") }]
|
||||||
|
});
|
||||||
|
} else if (nd.tagName == "INPUT") { //如果element是输入项
|
||||||
|
outputParameters.push({
|
||||||
|
"nodeType": 3,
|
||||||
|
"contentType": 0, // 内容类型
|
||||||
|
"relative": false, //是否为相对xpath路径
|
||||||
|
"name": "para" + (n++) + "_text",
|
||||||
|
"desc": "", //para描述
|
||||||
|
"relativeXpath": ndPath,
|
||||||
|
"exampleValues": [{ "num": 0, "value": nd.getAttribute("value") == null ? "" : nd.getAttribute("value") }]
|
||||||
|
});
|
||||||
|
} else { //其他所有情况
|
||||||
|
outputParameters.push({
|
||||||
|
"nodeType": 0,
|
||||||
|
"contentType": 0, // 内容类型
|
||||||
|
"relative": false, //是否为相对xpath路径
|
||||||
|
"name": "para" + (n++) + "_text",
|
||||||
|
"desc": "", //para描述
|
||||||
|
"relativeXpath": ndPath,
|
||||||
|
"exampleValues": [{ "num": 0, "value": ndText }]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// console.log(outputParameters);
|
||||||
|
let at2 = parseInt(new Date().getTime());
|
||||||
|
console.log("generateMultiParameters", at2, at, at2 - at);
|
||||||
|
generateValTable(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//处理子element,对于每个块中多出的特殊element, 需要特殊处理
|
||||||
|
function handleDescendents() {
|
||||||
|
let n = 1;
|
||||||
|
chrome.storage.local.get({ parameterNum: 1 }, function(items) {
|
||||||
|
let at = parseInt(new Date().getTime());
|
||||||
|
n = items.parameterNum;
|
||||||
|
clearParameters(); //清除原来的para列表
|
||||||
|
app._data.selectedDescendents = true;
|
||||||
|
for (let num = 0; num < nodeList.length; num++) {
|
||||||
|
let tnode = nodeList[num]["node"];
|
||||||
|
let stack = new Array(); //深度优先搜索遍历element
|
||||||
|
stack.push(tnode); //从此节点开始
|
||||||
|
while (stack.length > 0) {
|
||||||
|
let nd = stack.pop(); // 挨个取出element
|
||||||
|
if (nd.parentNode.tagName == "A" && nd.tagName == "SPAN") {
|
||||||
|
continue; //对A标签内的SPANelement不进行处理,剪枝, 此时子element根本不加入stack, 即实现了此功能
|
||||||
|
}
|
||||||
|
ndPath = readXPath(nd, 1, tnode);
|
||||||
|
let index = -1;
|
||||||
|
for (let i = 0; i < outputParameters.length; i++) {
|
||||||
|
if (outputParameters[i]["relativeXpath"] == ndPath) {
|
||||||
|
index = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
outputParameterNodes.push({
|
||||||
|
"node": nd,
|
||||||
|
"boxShadow": nd.style.boxShadow == "" || boxShadowColor ? "none" : nd.style.boxShadow
|
||||||
|
});
|
||||||
|
nd.style.boxShadow = boxShadowColor;
|
||||||
|
ndText = $(nd).contents().filter(function() {
|
||||||
|
return this.nodeType === 3;
|
||||||
|
}).text().replace(/\s+/g, '');
|
||||||
|
if (index == -1) { //从第二个节点开始, 只插入那些不在para列表中的element, 根据xpath进行寻址
|
||||||
|
//如果当前节点除了子element外仍然有其他文字或者该element是Image/表单项, 加入子element节点
|
||||||
|
if (ndText != "" || nd.tagName == "IMG" || nd.tagName == "INPUT" || nd.tagName == "A") {
|
||||||
|
if (nd.tagName == "IMG") { //如果element是Image
|
||||||
|
outputParameters.push({
|
||||||
|
"nodeType": 4, //节点类型
|
||||||
|
"contentType": 1, // 内容类型
|
||||||
|
"relative": nodeList.length > 1 ? true : false, //是否为相对xpath路径,注意当只selection了子element没有Select All的时候, 需要判断
|
||||||
|
"name": "para" + (n++) + "_imageAddress",
|
||||||
|
"desc": "", //para描述
|
||||||
|
"relativeXpath": nodeList.length > 1 ? ndPath : readXPath(nd), //同理需要判断
|
||||||
|
"exampleValues": [{
|
||||||
|
"num": num,
|
||||||
|
"value": nd.getAttribute("src") == null ? "" : $(nd).prop("src")
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
} else if (nd.tagName == "A") { //如果element是超链接
|
||||||
|
outputParameters.push({
|
||||||
|
"nodeType": 1,
|
||||||
|
"contentType": 0, // 内容类型
|
||||||
|
"relative": nodeList.length > 1 ? true : false, //是否为相对xpath路径
|
||||||
|
"name": "para" + (n++) + "_linktext",
|
||||||
|
"desc": "", //para描述
|
||||||
|
"relativeXpath": nodeList.length > 1 ? ndPath : readXPath(nd),
|
||||||
|
"exampleValues": [{ "num": num, "value": $(nd).text() }] //注意这里的ndtext是整个a的文字!!!
|
||||||
|
});
|
||||||
|
outputParameters.push({
|
||||||
|
"nodeType": 2,
|
||||||
|
"contentType": 0, // 内容类型
|
||||||
|
"relative": nodeList.length > 1 ? true : false, //是否为相对xpath路径
|
||||||
|
"name": "para" + (n++) + "_linkAddress",
|
||||||
|
"desc": "", //para描述
|
||||||
|
"relativeXpath": nodeList.length > 1 ? ndPath : readXPath(nd),
|
||||||
|
"exampleValues": [{
|
||||||
|
"num": num,
|
||||||
|
"value": nd.getAttribute("href") == null ? "" : $(nd).prop("href")
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
} else if (nd.tagName == "INPUT") { //如果element是输入项
|
||||||
|
outputParameters.push({
|
||||||
|
"nodeType": 3,
|
||||||
|
"contentType": 1, // 内容类型
|
||||||
|
"relative": nodeList.length > 1 ? true : false, //是否为相对xpath路径
|
||||||
|
"name": "para" + (n++) + "_text",
|
||||||
|
"desc": "", //para描述
|
||||||
|
"relativeXpath": nodeList.length > 1 ? ndPath : readXPath(nd),
|
||||||
|
"exampleValues": [{
|
||||||
|
"num": num,
|
||||||
|
"value": nd.getAttribute("value") == null ? "" : nd.getAttribute("value")
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
} else { //其他所有情况
|
||||||
|
outputParameters.push({
|
||||||
|
"nodeType": 0,
|
||||||
|
"contentType": 1, // 内容类型
|
||||||
|
"relative": nodeList.length > 1 ? true : false, //是否为相对xpath路径
|
||||||
|
"name": "para" + (n++) + "_text",
|
||||||
|
"desc": "", //para描述
|
||||||
|
"relativeXpath": nodeList.length > 1 ? ndPath : readXPath(nd),
|
||||||
|
"exampleValues": [{ "num": num, "value": ndText }]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else //如果element节点Already 经存在, 则只需要插入值就可以了
|
||||||
|
{
|
||||||
|
if (nd.tagName == "IMG") { //如果element是Image
|
||||||
|
outputParameters[index]["exampleValues"].push({
|
||||||
|
"num": num,
|
||||||
|
"value": nd.getAttribute("src") == null ? "" : $(nd).prop("src")
|
||||||
|
});
|
||||||
|
} else if (nd.tagName == "A") { //如果element是超链接
|
||||||
|
outputParameters[index]["exampleValues"].push({ "num": num, "value": $(nd).text() });
|
||||||
|
outputParameters[index + 1]["exampleValues"].push({
|
||||||
|
"num": num,
|
||||||
|
"value": nd.getAttribute("href") == null ? "" : $(nd).prop("href")
|
||||||
|
});
|
||||||
|
} else if (nd.tagName == "INPUT") { //如果element是输入项
|
||||||
|
outputParameters[index]["exampleValues"].push({
|
||||||
|
"num": num,
|
||||||
|
"value": nd.getAttribute("value") == null ? "" : nd.getAttribute("value")
|
||||||
|
});
|
||||||
|
} else { //其他所有情况
|
||||||
|
outputParameters[index]["exampleValues"].push({ "num": num, "value": ndText });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (let i = nd.children.length - 1; i >= 0; i--) {
|
||||||
|
stack.push(nd.children[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let at2 = parseInt(new Date().getTime());
|
||||||
|
console.log("Select child elements", at2, at, at2 - at);
|
||||||
|
generateValTable();
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//根据para列表生成可视化para界面
|
||||||
|
function generateValTable(multiline = true) {
|
||||||
|
let paravalues = [];
|
||||||
|
for (let i = 0; i < outputParameters.length; i++) {
|
||||||
|
let tvalues = [];
|
||||||
|
let tindex = 0;
|
||||||
|
let l = multiline ? nodeList.length : 1;
|
||||||
|
for (let j = 0; j < l; j++) {
|
||||||
|
//注意第一个循环条件, index超出界限了就不需要再寻找了, 其他的全是空
|
||||||
|
if (tindex < outputParameters[i]["exampleValues"].length && outputParameters[i]["exampleValues"][tindex]["num"] == j) {
|
||||||
|
tvalues.push(outputParameters[i]["exampleValues"][tindex]["value"]);
|
||||||
|
tindex++;
|
||||||
|
} else {
|
||||||
|
tvalues.push(" ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
paravalues.push(tvalues);
|
||||||
|
}
|
||||||
|
app._data.valTable = paravalues;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 选中第一个节点, 自动寻找同类节点
|
||||||
|
// 方法:/div[1]/div[2]/div[2]/a[1]
|
||||||
|
// 从倒数第一个节点开始找, 看去掉方括号之后是否element数目变多, 如上面的变成/div[1]/div[2]/div[2]/a
|
||||||
|
// 如果没有, 则恢复原状, 然后试试倒数第二个:/div[1]/div[2]/div/a[1]
|
||||||
|
// 直到找到第一个变多的节点或者追溯到根节点为止
|
||||||
|
function findRelated() {
|
||||||
|
let at = parseInt(new Date().getTime());
|
||||||
|
let testPath = nodeList[0]["xpath"].split("/").splice(1); //分离xpath成 ["html","body","div[0]"]这样子
|
||||||
|
let nodeNameList = [];
|
||||||
|
let nodeIndexList = [];
|
||||||
|
for (i = 0; i < testPath.length; i++) {
|
||||||
|
nodeNameList.push(testPath[i].split("[")[0]);
|
||||||
|
if (testPath[i].indexOf("[") >= 0) { //如果存在索引值
|
||||||
|
nodeIndexList.push(parseInt(testPath[i].split("[")[1].replace("]", ""))); //只留下数字
|
||||||
|
} else {
|
||||||
|
nodeIndexList.push(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var tempPath = "";
|
||||||
|
for (let i = nodeIndexList.length - 1; i >= 0; i--) {
|
||||||
|
if (nodeIndexList[i] == -1) { //没有索引值直接跳过
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
tempIndexList = [...nodeIndexList]; //复刻一个index数组
|
||||||
|
tempIndexList[i] = -1; //删除索引值
|
||||||
|
tempPath = combineXpath(nodeNameList, tempIndexList); //生成新的xpath
|
||||||
|
var result = document.evaluate(tempPath, document, null, XPathResult.ANY_TYPE, null);
|
||||||
|
result.iterateNext(); //枚举第一个element
|
||||||
|
if (result.iterateNext() != null) { //如果能枚举到第二个element, 说明存在同类element,选中同类element, 结束循环
|
||||||
|
app.$data.nowPath = tempPath; //标记此elementxpath
|
||||||
|
pushToReadyList(tempPath);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let at2 = parseInt(new Date().getTime());
|
||||||
|
console.log("findRelated:", at2, at, at2 - at);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//根据path将element放入readylist中
|
||||||
|
function pushToReadyList(path) {
|
||||||
|
result = document.evaluate(path, document, null, XPathResult.ANY_TYPE, null);
|
||||||
|
var node = result.iterateNext(); //枚举第一个element
|
||||||
|
while (node) { //只添加不在Already 选中列表内的element
|
||||||
|
let exist = false;
|
||||||
|
for (o of nodeList) {
|
||||||
|
if (o["node"] == node) {
|
||||||
|
exist = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!exist) {
|
||||||
|
readyList.push({ "node": node, "bgColor": node.style.backgroundColor, "boxShadow": node.style.boxShadow == "" || boxShadowColor ? "none" : node.style.boxShadow });
|
||||||
|
}
|
||||||
|
node.style.boxShadow = boxShadowColor;
|
||||||
|
node = result.iterateNext(); //枚举下一个element
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//将readyList中的element放入选中节点中
|
||||||
|
function readyToList(step, dealparameters = true) {
|
||||||
|
for (o of readyList) {
|
||||||
|
nodeList.push({ node: o["node"], "step": step, bgColor: o["bgColor"], "boxShadow": o["boxShadow"], xpath: readXPath(o["node"], 1) });
|
||||||
|
o["node"].style.backgroundColor = selectedColor;
|
||||||
|
}
|
||||||
|
clearReady();
|
||||||
|
if (dealparameters) { //防止出现先Select child elements再Select All失效的问题
|
||||||
|
generateParameters(0); //根据nodelist列表内的element生成para列表, 0代表纯text
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//根据节点列表和索引列表生成XPATH
|
||||||
|
// 如:["html","body","div"],[-1,-1,2],生成/html/body/div[2]
|
||||||
|
function combineXpath(nameList, indexList) {
|
||||||
|
let finalPath = "";
|
||||||
|
for (i = 0; i < nameList.length; i++) {
|
||||||
|
finalPath = finalPath + "/" + nameList[i];
|
||||||
|
if (indexList[i] != -1) {
|
||||||
|
finalPath = finalPath + "[" + indexList[i] + "]";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return finalPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
//专门测试Already 经选中的这些element之间有没有相关性
|
||||||
|
// 举例:
|
||||||
|
// /html/body/div[3]/div[1]/div[1]/div[1]/div[3]/div[1]/div[3]/a[22]
|
||||||
|
// /html/body/div[3]/div[1]/div[1]/div[1]/div[3]/div[2]/div[3]/a[25]
|
||||||
|
// 最终转换为:
|
||||||
|
// /html/body/div[3]/div[1]/div[1]/div[1]/div[3]/div/div[3]/a
|
||||||
|
function relatedTest() {
|
||||||
|
let at = new Date().getTime()
|
||||||
|
var testList = [];
|
||||||
|
var testpath = "";
|
||||||
|
for (i = 0; i < nodeList.length; i++) {
|
||||||
|
var testnumList = []; //用于比较节点索引号不同
|
||||||
|
var tpath = nodeList[i]["xpath"].split("/").splice(1); //清理第一个空element
|
||||||
|
for (j = 0; j < tpath.length; j++) {
|
||||||
|
if (tpath[j].indexOf("[") >= 0) { //如果存在索引值
|
||||||
|
testnumList.push(parseInt(tpath[j].split("[")[1].replace("]", ""))); //只留下数字
|
||||||
|
} else {
|
||||||
|
testnumList.push(-1);
|
||||||
|
}
|
||||||
|
tpath[j] = tpath[j].split("[")[0];
|
||||||
|
}
|
||||||
|
tp = tpath.join("/");
|
||||||
|
if (i > 0 && testpath != tp) { //如果去除括号后element内存在不一致情况, 直接返回默认情况代码100
|
||||||
|
app.$data.nowPath = ""; //标记此elementxpath
|
||||||
|
return 100;
|
||||||
|
}
|
||||||
|
testpath = tp;
|
||||||
|
testList.push(testnumList);
|
||||||
|
}
|
||||||
|
testpath = testpath.split("/"); //清理第一个空element
|
||||||
|
var indexList = []; //记录新生成的xpath
|
||||||
|
//如果选中的element属于同样的序列, 则计算出序列的最佳xpath表达式
|
||||||
|
for (j = 0; j < testList[0].length; j++) {
|
||||||
|
indexList.push(testList[0][j]);
|
||||||
|
for (i = 1; i < testList.length; i++) {
|
||||||
|
if (testList[i][j] != testList[i - 1][j]) {
|
||||||
|
indexList[j] = -1; //不一致就记录成-1
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var finalPath = combineXpath(testpath, indexList);
|
||||||
|
app.$data.nowPath = finalPath; //标记此elementxpath
|
||||||
|
pushToReadyList(finalPath);
|
||||||
|
let at2 = parseInt(new Date().getTime());
|
||||||
|
console.log("手动:", at2, at, at2 - at);
|
||||||
|
return 50; //先返回给默认码
|
||||||
|
}
|
||||||
|
|
||||||
|
//实现提示 box拖拽功能
|
||||||
|
$('.tooldrag').mousedown(function(e) {
|
||||||
|
// e.pageX
|
||||||
|
var positionDiv = $(this).offset();
|
||||||
|
var distanceX = e.pageX - positionDiv.left;
|
||||||
|
var distanceY = e.pageY - positionDiv.top;
|
||||||
|
//alert(distanceX)
|
||||||
|
// alert(positionDiv.left);
|
||||||
|
|
||||||
|
$(document).mousemove(function(e) {
|
||||||
|
var x = e.clientX - distanceX;
|
||||||
|
var y = e.clientY - distanceY;
|
||||||
|
|
||||||
|
if (x < 0) {
|
||||||
|
x = 0;
|
||||||
|
} else if (x > window.innerWidth - $('.tooldrag').outerWidth(true)) {
|
||||||
|
x = window.innerWidth - $('.tooldrag').outerWidth(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y < 0) {
|
||||||
|
y = 0;
|
||||||
|
} else if (y > window.innerHeight - $('.tooldrag').outerHeight(true)) {
|
||||||
|
y = window.innerHeight - $('.tooldrag').outerHeight(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
$('.tooltips').css({
|
||||||
|
'right': window.innerWidth - x - $('.tooltips').outerWidth(true) + 'px',
|
||||||
|
'bottom': window.innerHeight - y - $('.tooltips').outerHeight(true) + 'px',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).mouseup(function() {
|
||||||
|
$(document).off('mousemove');
|
||||||
|
});
|
||||||
|
});
|
1
Extension/EasySpider_mac/scripts/devtools.js
Normal file
1
Extension/EasySpider_mac/scripts/devtools.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
console.log(`'Allo 'Allo! Devtools Extension`)
|
2
Extension/EasySpider_mac/scripts/jquery-3.4.1.min.js
vendored
Normal file
2
Extension/EasySpider_mac/scripts/jquery-3.4.1.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
10598
Extension/EasySpider_mac/scripts/jquery.js
vendored
Normal file
10598
Extension/EasySpider_mac/scripts/jquery.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
165
Extension/EasySpider_mac/scripts/messageInteraction.js
Normal file
165
Extension/EasySpider_mac/scripts/messageInteraction.js
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
//实现与后台和流程图部分的交互
|
||||||
|
|
||||||
|
if (window.location.href.indexOf("backEndAddressServiceWrapper") >= 0) {
|
||||||
|
throw "serviceGrid"; //如果是服务器网页页面,则不执行工具
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
startMsg = { "type": 0, msg: "" };
|
||||||
|
|
||||||
|
chrome.runtime.sendMessage(startMsg, function(response) {
|
||||||
|
console.log(response.msg);
|
||||||
|
}); //每次打开新页面的时候需要告诉后台
|
||||||
|
console.log("test");
|
||||||
|
chrome.extension.onMessage.addListener(
|
||||||
|
function(request, sender, sendResponse) {
|
||||||
|
if (request["type"] == 1);
|
||||||
|
sendResponse("回答处理结果");
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
function input(value) {
|
||||||
|
let message = {
|
||||||
|
"type": "InputText",
|
||||||
|
"history": history.length, //记录history的长度
|
||||||
|
"tabIndex": -1,
|
||||||
|
"xpath": readXPath(nodeList[0]["node"], 0),
|
||||||
|
"alternativeXPaths": [],
|
||||||
|
"value": value,
|
||||||
|
};
|
||||||
|
let msg = { "type": 3, msg: message };
|
||||||
|
chrome.runtime.sendMessage(msg);
|
||||||
|
msg = { "type": 2, msg: value };
|
||||||
|
chrome.runtime.sendMessage(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
//点击元素操作
|
||||||
|
function sendSingleClick() {
|
||||||
|
let message = {
|
||||||
|
"type": "singleClick",
|
||||||
|
"history": history.length, //记录history的长度
|
||||||
|
"tabIndex": -1,
|
||||||
|
"useLoop": false, //是否使用循环内元素
|
||||||
|
"xpath": readXPath(nodeList[0]["node"], 0),
|
||||||
|
};
|
||||||
|
let msg = { "type": 3, msg: message };
|
||||||
|
chrome.runtime.sendMessage(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
//采集单个元素
|
||||||
|
function collectSingle() {
|
||||||
|
let message = {
|
||||||
|
"type": "singleCollect",
|
||||||
|
"history": history.length, //记录history的长度
|
||||||
|
"tabIndex": -1,
|
||||||
|
"parameters": outputParameters,
|
||||||
|
};
|
||||||
|
let msg = { "type": 3, msg: message };
|
||||||
|
chrome.runtime.sendMessage(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
//采集无规律多元素
|
||||||
|
function collectMultiNoPattern() {
|
||||||
|
let message = {
|
||||||
|
"type": "multiCollectNoPattern",
|
||||||
|
"history": history.length, //记录history的长度
|
||||||
|
"tabIndex": -1,
|
||||||
|
"parameters": outputParameters,
|
||||||
|
};
|
||||||
|
let msg = { "type": 3, msg: message };
|
||||||
|
chrome.runtime.sendMessage(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
//采集有规律多元素
|
||||||
|
function collectMultiWithPattern() {
|
||||||
|
//先点击选择全部然后再
|
||||||
|
let message = {
|
||||||
|
"type": "multiCollectWithPattern",
|
||||||
|
"history": history.length, //记录history的长度
|
||||||
|
"tabIndex": -1,
|
||||||
|
"loopType": 1,
|
||||||
|
"xpath": "", //默认值设置为空
|
||||||
|
"isDescendents": app._data.selectedDescendents, //标记是否采集的是子元素
|
||||||
|
"parameters": outputParameters,
|
||||||
|
};
|
||||||
|
if (!detectAllSelected()) //如果不是全部选中的话
|
||||||
|
{
|
||||||
|
message.loopType = 2; //固定元素列表
|
||||||
|
}
|
||||||
|
if (message.loopType == 1) {
|
||||||
|
message["xpath"] = app._data.nowPath;
|
||||||
|
} else { //固定元素列表
|
||||||
|
message["pathList"] = [];
|
||||||
|
for (let i = 0; i < nodeList.length; i++) {
|
||||||
|
message["pathList"].push(readXPath(nodeList[i]["node"], 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let msg = { "type": 3, msg: message };
|
||||||
|
chrome.runtime.sendMessage(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
//循环点击单个元素
|
||||||
|
function sendLoopClickSingle(name) {
|
||||||
|
let message = {
|
||||||
|
"type": "loopClickSingle",
|
||||||
|
"history": history.length, //记录history的长度
|
||||||
|
"tabIndex": -1,
|
||||||
|
"useLoop": true, //是否使用循环内元素
|
||||||
|
"xpath": readXPath(nodeList[0]["node"], 0),
|
||||||
|
"loopType": 0, //循环类型,0为单个元素
|
||||||
|
"nextPage": false, //是否循环点击下一页
|
||||||
|
};
|
||||||
|
if (name == "Elements in next page") {
|
||||||
|
message.nextPage = true;
|
||||||
|
}
|
||||||
|
let msg = { "type": 3, msg: message };
|
||||||
|
chrome.runtime.sendMessage(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
//循环点击每个元素
|
||||||
|
function sendLoopClickEvery() {
|
||||||
|
let message = {
|
||||||
|
"type": "loopClickEvery",
|
||||||
|
"history": history.length, //记录history的长度
|
||||||
|
"tabIndex": -1,
|
||||||
|
"xpath": "", //默认值设置为空
|
||||||
|
"useLoop": true, //是否使用循环内元素
|
||||||
|
"loopType": 1, //循环类型,1为不固定元素列表
|
||||||
|
};
|
||||||
|
if (!detectAllSelected()) //如果不是全部选中的话
|
||||||
|
{
|
||||||
|
message.loopType = 2; //固定元素列表
|
||||||
|
}
|
||||||
|
if (message.loopType == 1) {
|
||||||
|
message["xpath"] = app._data.nowPath;
|
||||||
|
} else { //固定元素列表
|
||||||
|
//有的网站像淘宝,每个元素都有一个独一无二的ID号,这时候就不适用用id进行xpath定位了,这个问题暂时搁置
|
||||||
|
message["pathList"] = [];
|
||||||
|
for (let i = 0; i < nodeList.length; i++) {
|
||||||
|
message["pathList"].push(readXPath(nodeList[i]["node"], 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let msg = { "type": 3, msg: message };
|
||||||
|
chrome.runtime.sendMessage(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
//检测是否xpath对应的元素被全选了,个数判断即可
|
||||||
|
function detectAllSelected() {
|
||||||
|
if (app._data.nowPath == "") {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
let num = 0;
|
||||||
|
let result = document.evaluate(app._data.nowPath, document, null, XPathResult.ANY_TYPE, null);
|
||||||
|
var node = result.iterateNext(); //枚举第一个元素
|
||||||
|
while (node) {
|
||||||
|
// console.log(node.innerHTML);
|
||||||
|
num++;
|
||||||
|
node = result.iterateNext();
|
||||||
|
}
|
||||||
|
if (num == nodeList.length) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
1
Extension/EasySpider_mac/scripts/options.js
Normal file
1
Extension/EasySpider_mac/scripts/options.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
console.log(`'Allo 'Allo! Options`)
|
1
Extension/EasySpider_mac/scripts/popup.js
Normal file
1
Extension/EasySpider_mac/scripts/popup.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
console.log(`'Allo 'Allo! Popup`)
|
11965
Extension/EasySpider_mac/scripts/vue.js
Normal file
11965
Extension/EasySpider_mac/scripts/vue.js
Normal file
File diff suppressed because it is too large
Load Diff
139
Extension/EasySpider_mac/styles/contentscript.css
Normal file
139
Extension/EasySpider_mac/styles/contentscript.css
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
.tooltips {
|
||||||
|
width: 330px;
|
||||||
|
min-height: 300px;
|
||||||
|
background-color: white;
|
||||||
|
position: fixed;
|
||||||
|
z-index: 2147483647;
|
||||||
|
right: 30px;
|
||||||
|
bottom: 30px;
|
||||||
|
font-size: 13px!important;
|
||||||
|
font-weight: normal!important;
|
||||||
|
border: solid navy 2px;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
/* 文字不可被选中 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooldrag {
|
||||||
|
background-color: navy;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 13px;
|
||||||
|
height: 26px!important;
|
||||||
|
padding-top: 8px!important;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.realcontent {
|
||||||
|
text-align: left;
|
||||||
|
padding-top: 10px!important;
|
||||||
|
padding-bottom: 80px!important;
|
||||||
|
padding-left: 20px!important;
|
||||||
|
padding-right: 10px!important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.innercontent {
|
||||||
|
text-align: left;
|
||||||
|
padding-top: 5px!important;
|
||||||
|
padding-left: 12px!important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.innercontent a {
|
||||||
|
display: inline-block;
|
||||||
|
text-decoration: none;
|
||||||
|
margin-top: 2px!important;
|
||||||
|
font-size: 13px;
|
||||||
|
color: navy!important;
|
||||||
|
cursor: pointer;
|
||||||
|
text-decoration: none!important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.innercontent a:hover {
|
||||||
|
color: blue!important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.innercontent span {
|
||||||
|
font-size: 20px;
|
||||||
|
color: navy;
|
||||||
|
line-height: normal;
|
||||||
|
padding-left: 5px!important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltips button {
|
||||||
|
margin-top: 7px!important;
|
||||||
|
font-size: 13px;
|
||||||
|
border-radius: 5px;
|
||||||
|
border: solid 2px navy;
|
||||||
|
background-color: white;
|
||||||
|
color: navy;
|
||||||
|
width: 100px;
|
||||||
|
height: 30px;
|
||||||
|
cursor: pointer;
|
||||||
|
margin-left: 15px!important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltips input[type=text] {
|
||||||
|
display: block;
|
||||||
|
margin-top: 7px!important;
|
||||||
|
padding-left: 5px!important;
|
||||||
|
margin-bottom: 7px!important;
|
||||||
|
font-size: 15px;
|
||||||
|
border-radius: 5px;
|
||||||
|
border: solid 2px navy;
|
||||||
|
width: 204px;
|
||||||
|
height: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltips button:hover {
|
||||||
|
color: blue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 下面用来对冻结表格首行元素和固定表格宽度和高度设定样式 */
|
||||||
|
|
||||||
|
.toolkitcontain {
|
||||||
|
border: 1px solid #cdd!important;
|
||||||
|
width: 250px!important;
|
||||||
|
/* 上面的宽度设定很重要 */
|
||||||
|
height: 150px;
|
||||||
|
overflow: auto;
|
||||||
|
margin-top: 10px!important;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toolkitcontain table {
|
||||||
|
table-layout: fixed;
|
||||||
|
word-break: break-all;
|
||||||
|
word-wrap: break-word;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toolkitcontain th,
|
||||||
|
.toolkitcontain td,
|
||||||
|
.toolkitcontain tr {
|
||||||
|
border: 1px solid rgb(78, 78, 78)!important;
|
||||||
|
height: 25px!important;
|
||||||
|
width: 100px!important;
|
||||||
|
text-align: center!important;
|
||||||
|
font-weight: normal!important;
|
||||||
|
overflow: hidden!important;
|
||||||
|
font-size: 11px!important;
|
||||||
|
padding-left: 1px!important;
|
||||||
|
padding-right: 0px!important;
|
||||||
|
padding-top: 0px!important;
|
||||||
|
padding-bottom: 0px!important
|
||||||
|
}
|
||||||
|
|
||||||
|
.toolkitcontain .toolkittb2 {
|
||||||
|
position: sticky;
|
||||||
|
top: 0px;
|
||||||
|
margin-bottom: 0px;
|
||||||
|
background-color: azure;
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toolkitcontain .toolkittb4 {
|
||||||
|
position: absolute;
|
||||||
|
}
|
0
Extension/EasySpider_mac/styles/devtools.css
Normal file
0
Extension/EasySpider_mac/styles/devtools.css
Normal file
0
Extension/EasySpider_mac/styles/options.css
Normal file
0
Extension/EasySpider_mac/styles/options.css
Normal file
0
Extension/EasySpider_mac/styles/popup.css
Normal file
0
Extension/EasySpider_mac/styles/popup.css
Normal file
Loading…
x
Reference in New Issue
Block a user