diff --git a/README.md b/README.md
index 7f999b1..0c6581b 100644
--- a/README.md
+++ b/README.md
@@ -15,9 +15,6 @@
-
-
-
@@ -37,7 +34,9 @@
## 💽 安装地址
-- **[安装地址(推荐)](https://www.youxiaohou.com/tool/install-panai.html)**
+- **[安装地址(源地址)](https://raw.githubusercontent.com/xiaofeiTM233/panAI/main/panai.user.js)**
+- **[安装地址(jsdelivr镜像地址)](https://cdn.jsdelivr.net/gh/xiaofeiTM233/panAI@main/panai.user.js)**
+- **[安装地址(ghproxy镜像地址)](https://ghproxy.net/https://raw.githubusercontent.com/xiaofeiTM233/panAI/main/panai.user.js)**
## 📖 使用说明
@@ -47,71 +46,21 @@

-## 📖 更新日志
-
-**v1.9.5** 添加对 **新浪微盘/文叔叔网盘/14个小众网盘** 链接的识别 #31;修复链接中含有pwd字段时优先使用该字段作为密码 #22。感谢 [@52fisher](https://github.com/52fisher)。
-
-**v1.9.1** 添加对 **Mega网盘** 链接的识别 #22 支持自定义识别快捷键 #30;修复蓝奏云识别错误 #23 错误的识别链接 #16。感谢 [@52fisher](https://github.com/52fisher)。
-
-**v1.8.9** 添加对阿里云盘新域名 www.alipan.com 分享链接的支持。
-
-**v1.8.6** 增强选中文字含有超链接时的识别能力。感谢 [@taozhiyu](https://github.com/taozhiyu)。
-
-**v1.8.5** 增强对移动云盘的识别的识别能力。
-
-**v1.8.4** 提升对提取码的识别能力,能更智能的识别提取码。
-
-**v1.8.3** 添加对 **FlowUs息流** 链接的识别;**弹出提示时按下 Enter 回车键可以快速打开,按下 Esc 键可以关闭弹窗提示**。
-
-**v1.8.1** 更换更清晰的图标。新增对 **Mircosoft 应用商店**链接的识别,选中后自动跳转到对应可直接访问的镜像站点。[选中我试试看](https://apps.microsoft.com/store/detail/wechat-for-windows/9NBLGGH4SLX7)。
-
-**v1.8.0** 添加对 **百度企业网盘,百度网盘文档,115网盘,奶牛快传,城通网盘,夸克网盘** 链接的识别。
-
-**v1.7.0** 添加剪切板文本识别,可在脚本菜单中选择 `识别剪切板中文字`(可以按 F1 快速打开),在弹出的窗口中粘贴需要识别的链接。
-
-**v1.6.0** 添加对 **360云盘** 链接的识别,新增对 **Chrome 扩展商店,Edge 扩展商店,Firefox 扩展商店**链接的识别,选中后自动跳转到对应可直接访问的镜像站点。[选中我试试看](https://chrome.google.com/webstore/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo)。
-
-**v1.5.6** 支持将链接中含“点”自动替换为“.”后识别,加强阿里云盘的识别。
-
-**v1.5.4** 修复链接本身包含提取码无法识别的问题,如 https://pan.baidu.com/s/xxxx?**pwd=1234**。
-
-**v1.5.2** CDN 从 cdn.jsdelivr.net 替换为 unpkg.com。
-
-**v1.5.1** 支持识别到 lanzous.com,就自动转换到可以访问的域名 lanzouw.com
-
-**v1.5.0** 添加对 **123云盘** 链接的识别,支持超链接形式的识别([选中密码和我试试看](https://www.lanzoui.com/b00t5sclg) 密码:d8f9)。
-
-**v1.4.3** 增强对蓝奏云新链接的识别。
-
-**v1.4.2** 增强对蓝奏云链接的识别。
-
-**v1.4.1** 添加对阿里云盘短链接 alywp.net 的识别,增强对蓝奏云自定义链接的识别。
-
-**v1.4.0** 添加对 **阿里云盘** 链接的识别,见测试链接 - 阿里云盘。
-
-**v1.3.2** 支持识别更多天翼云盘链接格式。
-
-**v1.3.1** 支持识别到 lanzous.com,就自动转换到可以访问的域名 lanzoui.com
-
-**v1.3.0** 添加了对 **迅雷网盘** 链接的识别,改进了对链接中含有零宽度字符时无法识别的问题,修复和彩云无法自动填写的 Bug。
-
-**v1.2.0** 修复了设置选项出现在 iframe 里的情况,优化了自动点击提交按钮的逻辑。
-
-**v1.1.1** 修正了在部分网站上样式无法加载的问题。
-
-**v1.1.0** 修正了弹出框在百度搜索上样式错乱的问题,部分网站弹出框被覆盖的问题,支持 iframe 网页内识别。
-
-**v1.0.6** 支持对 `http删s://pan.b厨aidu.co次m/s/xxxx闷xxx` 这种中间含有汉字等特殊符号的识别。
-
-**v1.0.5** 支持连续识别,增强对百度网盘的链接识别。
-
-**v1.0.3** 增强识别准确度,对提取码判断更加准确。
-
-**v1.0.2** 添加对不带 https 的链接识别,修复部分网站设置弹出框字体过大的提示。
-
-**v1.0.1** 添加对 **和彩云** 链接的识别。
-
-**v1.0.0** 添加对 **百度网盘,腾讯微云,蓝奏云,天翼云盘** 链接的识别。
+## 📖 添加自定义网盘的参数说明
+line111行,使用opt对象来管理所有支持的网盘列表和信息,opt的key即为不同网站的名称缩写,key的子对象即为该网站的具体配置,参数说明如下:
+```javascript
+'noire': {
+reg: /(?:https?:\/\/)?drive.noire.cc\/s\/\w+/, //网盘链接的正则表达式,用于匹配链接
+host: /drive\.noire\.cc/,//网盘链接的host,用于匹配链接
+input: ['#pwd'], //密码输入框的选择器,用于获取密码输入框的元素
+button: ['button.MuiButton-containedSecondary'],//密码输入框的确认按钮的选择器,用于获取确认按钮的元素
+name: '爱丽丝的记事本',//网盘名称
+storage: 'local',//密码存储方式,可选local或hash,使用hash时会在链接中添加pwd参数和pwd的hash,使用local时会在本地存储密码
+storagePwdName: 'tmp_noire_pwd',//密码存储的名称,使用local方式存储密码能通过该值获取对应的密码
+originalLink:true,//是否保留原始链接,当参数值为true时,会保留原始链接,不会拼接pwd参数和pwd的hash,以解决部分网站路由跳转不对的问题
+replaceHost: 'drive.noire.cc',//替换链接的host,用于替换链接中的host,解决部分网站路由跳转不对的问题
+},
+```
## 🎨 GIF演示
diff --git a/panai.user.js b/panai.user.js
index a4ea229..9209a0e 100644
--- a/panai.user.js
+++ b/panai.user.js
@@ -1,14 +1,14 @@
// ==UserScript==
-// @name 网盘智能识别助手
-// @namespace https://github.com/syhyz1990/panAI
-// @version 2.0.2
-// @author YouXiaoHou,52fisher
-// @description 智能识别选中文字中的🔗网盘链接和🔑提取码,识别成功打开网盘链接并自动填写提取码,省去手动复制提取码在输入的烦恼。支持识别 ✅百度网盘 ✅阿里云盘 ✅腾讯微云 ✅蓝奏云 ✅天翼云盘 ✅移动云盘 ✅迅雷云盘 ✅123云盘 ✅360云盘 ✅115网盘 ✅奶牛快传 ✅城通网盘 ✅夸克网盘 ✅FlowUs息流 ✅Chrome 扩展商店 ✅Edge 扩展商店 ✅Firefox 扩展商店 ✅Windows 应用商店。
+// @name 网盘智能识别助手(持续更新版)
+// @namespace panAI
+// @version 3.0.2
+// @author YouXiaoHou,52fisher,xiaofeiTM233
+// @description 智能识别选中文字中的🔗网盘链接和🔑提取码,识别成功打开网盘链接并自动填写提取码,省去手动复制提取码在输入的烦恼。支持识别 ✅百度网盘 ✅阿里云盘 ✅腾讯微云 ✅蓝奏云 ✅天翼云盘 ✅移动云盘 ✅迅雷云盘 ✅123云盘 ✅360云盘 ✅115网盘 ✅奶牛快传 ✅城通网盘 ✅夸克网盘 ✅Google云端硬盘 ✅FlowUs息流 ✅Chrome 扩展商店 ✅Edge 扩展商店 ✅Firefox 扩展商店 ✅Windows 应用商店。
// @license AGPL-3.0-or-later
// @homepage https://www.youxiaohou.com/tool/install-panai.html
-// @supportURL https://github.com/syhyz1990/panAI
-// @updateURL https://www.youxiaohou.com/panai.user.js
-// @downloadURL https://www.youxiaohou.com/panai.user.js
+// @supportURL https://github.com/xiaofeiTM233/panAI
+// @updateURL https://fastly.jsdelivr.net/gh/xiaofeiTM233/panAI/panai.user.js
+// @downloadURL https://fastly.jsdelivr.net/gh/xiaofeiTM233/panAI/panai.user.js
// @match *://*/*
// @require https://unpkg.com/sweetalert2@10.16.6/dist/sweetalert2.min.js
// @require https://unpkg.com/hotkeys-js@3.13.3/dist/hotkeys.min.js
@@ -115,7 +115,9 @@
input: ['#accessCode', '.share-access-code', '#wpdoc-share-page > .u-dialog__wrapper .u-input__inner'],
button: ['#submitBtn', '.share-access .g-button', '#wpdoc-share-page > .u-dialog__wrapper .u-btn--primary'],
name: '百度网盘',
- storage: 'hash'
+ storage: 'hash',
+ autoCompleteReg: /(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])\b[\w-]{23}\b/,
+ autoCompleteUrlPrefix: 'https://pan.baidu.com/s/'
},
'aliyun': {
reg: /((?:https?:\/\/)?(?:(?:www\.)?(?:aliyundrive|alipan)\.com\/s|alywp\.net)\/[a-zA-Z\d]+)/,
@@ -134,11 +136,19 @@
storage: 'hash'
},
'lanzou': {
- reg: /((?:https?:\/\/)?(?:[a-zA-Z0-9\-.]+)?(?:lanzou[a-z]|lanzn)\.com\/[a-zA-Z\d_\-]+(?:\/[\w-]+)?)/,
- host: /(?:[a-zA-Z\d-.]+)?(?:lanzou[a-z]|lanzn)\.com/,
+ reg: /((?:https?:\/\/)?(?:[a-zA-Z0-9\-.]+)?(?:lanzou[a-z]|lanzn|lanpv)\.com\/[a-zA-Z\d_\-]+(?:\/[\w-]+)?)/,
+ host: /(?:[a-zA-Z\d-.]+)?(?:lanzou[a-z]|lanzn|lanpv)\.com/,
input: ['#pwd'],
button: ['.passwddiv-btn', '#sub'],
name: '蓝奏云',
+ storage: 'hash',
+ },
+ 'ilanzou': {
+ reg: /(?:https?:\/\/)?(?:[a-zA-Z0-9\-.]+)?ilanzou\.com\/s\/[?=\w-]+/,
+ host: /www\.ilanzou\.com/,
+ input: ['.code-input'],
+ button: ['.code-checkbefore'],
+ name: '蓝奏云优享版',
storage: 'hash'
},
'tianyi': {
@@ -165,14 +175,17 @@
input: ['.pass-input-wrap .td-input__inner'],
button: ['.pass-input-wrap .td-button'],
name: '迅雷云盘',
- storage: 'hash'
+ storage: 'hash',
+ autoCompleteReg: /(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])\b[\w-]{26}\b/,
+ autoCompleteUrlPrefix: 'https://pan.xunlei.com/s/'
},
'123pan': {
- reg: /((?:https?:\/\/)?www\.123pan\.com\/s\/[\w-]{6,})/,
- host: /www\.123pan\.com/,
+ reg: /((?:https?:\/\/)?www\.123(\d{3}|pan)\.com\/s\/[\w-]{6,})/,
+ host: /www\.123(\d{3}|pan)\.com/,
input: ['.ca-fot input', ".appinput .appinput"],
button: ['.ca-fot button', ".appinput button"],
name: '123云盘',
+ replaceHost: "www.123pan.com",
storage: 'hash'
},
'360': {
@@ -211,11 +224,19 @@
'quark': {
reg: /((?:https?:\/\/)?pan\.quark\.cn\/s\/[a-zA-Z\d-]+)/,
host: /pan\.quark\.cn/,
- input: ['.ant-input'],
+ input: ['input[class*=ShareReceive]'],
button: ['.ant-btn-primary'],
name: '夸克网盘',
storage: 'local',
- storagePwdName: 'tmp_quark_pwd'
+ storagePwdName: 'tmp_quark_pwd',
+ autoCompleteReg: /(?=.*[a-z])(?=.*[0-9])\b[a-z0-9]{12}\b/,
+ autoCompleteUrlPrefix: 'https://pan.quark.cn/s/'
+ },
+ 'feijipan': {
+ reg: /((?:https?:\/\/)?share\.feijipan\.com\/s\/[a-zA-Z\d-]+)/,
+ host: /share\.feijipan\.com/,
+ name: '飞机盘',
+ storage: 'hash'
},
'vdisk': {
reg: /(?:https?:\/\/)?vdisk.weibo.com\/lc\/\w+/,
@@ -266,6 +287,11 @@
name: 'Mega',
storage: 'local'
},
+ 'qfile': {
+ reg: /((?:https?:\/\/)?qfile\.qq\.com\/q\/[0-9a-zA-Z]+)/,
+ host: /qfile\.qq\.com/,
+ name: 'QQ闪传',
+ },
'520vip': {
reg: /((?:https?:\/\/)?www\.(?:520-vip|eos-53)\.com\/file-\d+\.html)/,
host: /www\.520-vip\.com/,
@@ -277,6 +303,11 @@
name: '567盘',
replaceHost: "www.567inc.com",
},
+ 'seewopinco': {
+ reg: /((?:https?:\/\/)?pinco\.seewo\.com\/s\/[0-9a-zA-Z]+)/,
+ host: /www\.ayunpan\.com/,
+ name: '希沃品课',
+ },
'ayunpan': {
reg: /((?:https?:\/\/)?www\.ayunpan\.com\/file-\d+\.html)/,
host: /www\.ayunpan\.com/,
@@ -327,6 +358,11 @@
host: /www\.feiyunfile\.com/,
name: '飞云网盘',
},
+ 'google': {
+ reg: /(?:https?:\/\/)?drive\.google\.com\/file\/d\/\w+/,
+ host: /drive\.google\.com/,
+ name: 'Google云端硬盘',
+ },
'yifile': {
reg: /(?:https?:\/\/)?www\.yifile\.com\/f\/\w+/,
host: /www\.yifile\.com/,
@@ -386,6 +422,12 @@
}, {
name: 'setting_timer_open',
value: false
+ }, {
+ name: 'setting_auto_complete',
+ value: false
+ }, {
+ name: 'setting_text_as_password',
+ value: false
}, {
name: 'setting_timer',
value: 5000
@@ -423,11 +465,15 @@
smartIdentify(event, str = '') {
let selection = window.getSelection();
let text = str || this.getSelectionHTML(selection);
+ //自动推导网盘前缀的开关
+ const isAutoComplete = util.getValue('setting_auto_complete');
+ const isTextAsPassword = util.getValue('setting_text_as_password');
if (text !== this.lastText && text !== '') { //选择相同文字或空不识别
let start = performance.now();
this.lastText = text;
- //util.clog(`当前选中文字:${text}`);
+ util.clog(`当前选中文字:${text}`);
let linkObj = this.parseLink(text);
+ util.clog(`解析结果:${JSON.stringify(linkObj)}`);
let link = linkObj.link;
let name = linkObj.name;
let pwd = this.parsePwd(text);
@@ -436,6 +482,14 @@
link = linkObj.link;
name = linkObj.name;
}
+ if (isTextAsPassword && !pwd) {
+ pwd = this.parseLinkInnerTextAsPwd(selection);
+ }
+ if (isAutoComplete && !link) {
+ linkObj = this.parseLink(text, true);
+ link = linkObj.link;
+ name = linkObj.name;
+ }
if (link) {
if (!/https?:\/\//.test(link)) {
link = 'https://' + link;
@@ -467,14 +521,14 @@
util.setValue(linkObj.storagePwdName, pwd);
}
let active = util.getValue('setting_active_in_front');
- if (pwd) {
+ if (pwd && !linkObj.originalLink) {
let extra = `${link}?pwd=${pwd}#${pwd}`;
if (~link.indexOf('?')) {
extra = `${link}&pwd=${pwd}#${pwd}`;
}
- GM_openInTab(extra, {active});
+ GM_openInTab(extra, { active });
} else {
- GM_openInTab(`${link}`, {active});
+ GM_openInTab(`${link}`, { active });
}
}
});
@@ -503,29 +557,39 @@
},
//正则解析网盘链接
- parseLink(text = '') {
- let obj = {name: '', link: '', storage: '', storagePwdName: ''};
- if (text) {
- try {
- text = decodeURIComponent(text);
- } catch {
+ parseLink(text = '', autoCompletePrefix = false) {
+ let obj = { name: '', link: '', storage: '', storagePwdName: '' };
+ if (!text) {
+ return obj;
+ }
+ try {
+ text = decodeURIComponent(text);
+ } catch {
+ }
+ text = text.replace(/[点點]/g, '.');
+ text = text.replace(/[\u4e00-\u9fa5()(),\u200B,\uD83C-\uDBFF\uDC00-\uDFFF]/g, '');
+ text = text.replace(/lanzous/g, 'lanzouw'); //修正lanzous打不开的问题
+
+ for (let name in opt) {
+ let item = opt[name];
+ //要求补全链接的前缀应提前加入对应位置
+ if (autoCompletePrefix && item.hasOwnProperty('autoCompleteReg')) {
+ console.log('%cpanai.user.js:554 autoCompletePrefix,text', 'color: #007acc;', autoCompletePrefix,text);
+ text = text.replace(item.autoCompleteReg, item.autoCompleteUrlPrefix + "$&");
}
- text = text.replace(/[点點]/g, '.');
- text = text.replace(/[\u4e00-\u9fa5()(),\u200B,\uD83C-\uDBFF\uDC00-\uDFFF]/g, '');
- text = text.replace(/lanzous/g, 'lanzouw'); //修正lanzous打不开的问题
- for (let name in opt) {
- let val = opt[name];
- if (val.reg.test(text)) {
- let matches = text.match(val.reg);
- obj.name = val.name;
- obj.link = matches[0];
- obj.storage = val.storage;
- obj.storagePwdName = val.storagePwdName || null;
- if (val.replaceHost) {
- obj.link = obj.link.replace(val.host, val.replaceHost);
- }
- return obj;
+ if (item.reg.test(text)) {
+ console.log(`匹配文本:${text} 正则:${item.reg},名称:${item.name},开关:${autoCompletePrefix}`);
+ console.log('%cpanai.user.js:556 autoCompletePrefix,item', 'color: #007acc;', autoCompletePrefix,item);
+ let matches = text.match(item.reg);
+ obj.name = item.name;
+ obj.link = matches[0];
+ obj.storage = item.storage;
+ obj.storagePwdName = item.storagePwdName || null;
+ obj.originalLink = item.originalLink || false;
+ if (item.replaceHost) {
+ obj.link = obj.link.replace(item.host, item.replaceHost);
}
+ return obj;
}
}
return obj;
@@ -536,12 +600,20 @@
const dom = this.getSelectionHTML(selection, true).querySelector('*[href]');
return this.parseLink(dom ? dom.href : "");
},
-
+ //将超链接的文本内容作为提取码
+ parseLinkInnerTextAsPwd(selection) {
+ const dom = this.getSelectionHTML(selection, true).querySelector('*[href]');
+ //提取码仅支持英文大小写、数字,需要提前检验
+ if (/^[a-zA-Z0-9]+$/.test(dom ? dom.innerText: '')) {
+ return dom.innerText;
+ }
+ return '';
+ },
//正则解析提取码
parsePwd(text) {
text = text.replace(/\u200B/g, '').replace('%3A', ":");
text = text.replace(/(?:本帖)?隐藏的?内容[::]?/, "");
- let reg = /wss:[a-zA-Z0-9]+|(?<=\s*(?:密|提取|访问|訪問|key|password|pwd|#|\?p=)\s*[码碼]?\s*[::=]?\s*)[a-zA-Z0-9]{3,8}/i;
+ let reg = /wss:[a-zA-Z0-9]+|(?<=\s*(?:密|提取|访问|訪問|key|password|pwd|#|\?p=|\?code=)\s*[码碼]?\s*[::=]?\s*)[a-zA-Z0-9]{3,8}/i;
if (reg.test(text)) {
let match = text.match(reg);
return match[0];
@@ -609,7 +681,7 @@
let lastValue = input.value;
input.value = pwd;
//Vue & React 触发 input 事件
- let event = new Event('input', {bubbles: true});
+ let event = new Event('input', { bubbles: true });
let tracker = input._valueTracker;
if (tracker) {
tracker.setValue(lastValue);
@@ -664,7 +736,7 @@
navigator.clipboard.readText().then(text => {
this.smartIdentify(null, text);
}).catch(() => {
- toast.fire({title: '读取剪切板失败,请先授权或手动粘贴后识别!', icon: 'error'});
+ toast.fire({ title: '读取剪切板失败,请先授权或手动粘贴后识别!', icon: 'error' });
});
}
});
@@ -674,10 +746,11 @@
showSettingBox() {
let html = `
-
+
+
+
`;
Swal.fire({
@@ -686,7 +759,7 @@
icon: 'info',
showCloseButton: true,
confirmButtonText: '保存',
- footer: '
',
+ footer: '
',
customClass
}).then((res) => {
res.isConfirmed && history.go(0);
@@ -703,6 +776,13 @@
e.target.checked ? rangeWrapper.style.display = 'flex' : rangeWrapper.style.display = 'none';
util.setValue('setting_timer_open', e.target.checked);
});
+ document.getElementById('S-Auto-Complete').addEventListener('change', (e) => {
+ util.setValue('setting_auto_complete', e.target.checked);
+ console.log('%cpanai.user.js:746 checked', 'color: #007acc;', 'setting_auto_complete', e.target.checked," test");
+ })
+ document.getElementById('S-Text-As-Password').addEventListener('change', (e) => {
+ util.setValue('setting_text_as_password', e.target.checked);
+ });
document.getElementById('S-Timer').addEventListener('change', (e) => {
util.setValue('setting_timer', e.target.value);
document.getElementById('Timer-Value').innerText = `(${e.target.value / 1000}秒)`;
@@ -741,7 +821,7 @@
util.addStyle('swal-pub-style', 'style', GM_getResourceText('swalStyle'));
util.addStyle('panai-style', 'style', style);
});
- headObserver.observe(document.head, {childList: true, subtree: true});
+ headObserver.observe(document.head, { childList: true, subtree: true });
},
isTopWindow() {