蓝奏云网盘增强

刷新不回根目录、后退返回上一级、右键文件显示菜单、自动显示更多文件、自动打开分享链接、自动复制分享链接、带密码的分享链接自动输密码、拖入文件自动显示上传框、输入密码后回车确认、调整描述(话说)编辑框初始大小

Version au 22/05/2021. Voir la dernière version.

  1. // ==UserScript==
  2. // @name 蓝奏云网盘增强
  3. // @version 1.2.7
  4. // @author X.I.U
  5. // @description 刷新不回根目录、后退返回上一级、右键文件显示菜单、自动显示更多文件、自动打开分享链接、自动复制分享链接、带密码的分享链接自动输密码、拖入文件自动显示上传框、输入密码后回车确认、调整描述(话说)编辑框初始大小
  6. // @match *://*.lanzous.com/*
  7. // @match *://*.lanzoux.com/*
  8. // @match *://*.lanzoui.com/*
  9. // @match *://pan.lanzou.com/*
  10. // @match *://lanzou.com/u
  11. // @match *://www.lanzou.com/account.php*
  12. // @match *://www.lanzou.com/u
  13. // @match *://up.woozooo.com/u
  14. // @match *://up.woozooo.com/mydisk.php*
  15. // @match *://pc.woozooo.com/u
  16. // @match *://pc.woozooo.com/mydisk.php*
  17. // @icon https://www.lanzou.com/favicon.ico
  18. // @grant GM_xmlhttpRequest
  19. // @grant GM_registerMenuCommand
  20. // @grant GM_unregisterMenuCommand
  21. // @grant GM_openInTab
  22. // @grant GM_getValue
  23. // @grant GM_setValue
  24. // @grant GM_notification
  25. // @grant unsafeWindow
  26. // @noframes
  27. // @license GPL-3.0 License
  28. // @run-at document-end
  29. // @namespace https://github.com/XIU2/UserScript
  30. // ==/UserScript==
  31. (function() {
  32. var menu_ALL = [
  33. ['menu_open_fileSha', '自动打开分享链接', '自动打开分享链接', true],
  34. ['menu_copy_fileSha', '自动复制分享链接', '自动复制分享链接', true],
  35. ['menu_refreshCorrection', '刷新不返回根目录', '刷新不返回根目录', true],
  36. ['menu_rightClickMenu', '右键文件显示菜单', '右键文件显示菜单', true],
  37. ['menu_folderDescdesMenu', '调整描述(话说)编辑框大小', '调整描述(话说)编辑框大小', true]
  38. ], menu_ID = [], lastFolderID;
  39. for (let i=0;i<menu_ALL.length;i++){ // 如果读取到的值为 null 就写入默认值
  40. if (GM_getValue(menu_ALL[i][0]) == null){GM_setValue(menu_ALL[i][0], menu_ALL[i][3])};
  41. }
  42. registerMenuCommand();
  43.  
  44. // 注册脚本菜单
  45. function registerMenuCommand() {
  46. if (menu_ID.length > menu_ALL.length){ // 如果菜单ID数组多于菜单数组,说明不是首次添加菜单,需要卸载所有脚本菜单
  47. for (let i=0;i<menu_ID.length;i++){
  48. GM_unregisterMenuCommand(menu_ID[i]);
  49. }
  50. }
  51. for (let i=0;i<menu_ALL.length;i++){ // 循环注册脚本菜单
  52. menu_ALL[i][3] = GM_getValue(menu_ALL[i][0]);
  53. if (menu_ALL[i][0] == 'menu_refreshCorrection') {
  54. menu_ID[i] = GM_registerMenuCommand(`[ ${menu_ALL[i][3]?'√':'×'} ] ${menu_ALL[i][1]}`, function(){if(menu_value('menu_refreshCorrection')){UNrefreshCorrection();}else{refreshCorrection();};menu_switch(`${menu_ALL[i][3]}`,`${menu_ALL[i][0]}`,`${menu_ALL[i][2]}`)});
  55. }else{
  56. menu_ID[i] = GM_registerMenuCommand(`[ ${menu_ALL[i][3]?'√':'×'} ] ${menu_ALL[i][1]}`, function(){menu_switch(`${menu_ALL[i][3]}`,`${menu_ALL[i][0]}`,`${menu_ALL[i][2]}`)});
  57. }
  58. }
  59. menu_ID[menu_ID.length] = GM_registerMenuCommand('反馈 & 建议', function () {window.GM_openInTab('https://github.com/XIU2/UserScript#xiu2userscript', {active: true,insert: true,setParent: true});window.GM_openInTab('https://greasyfork.org/zh-CN/scripts/419224/feedback', {active: true,insert: true,setParent: true});});
  60. }
  61.  
  62. // 菜单开关
  63. function menu_switch(menu_status, Name, Tips) {
  64. let RefreshTips = '\n(刷新网页后生效)';
  65. if (Name == 'menu_refreshCorrection')RefreshTips = ''
  66. if (menu_status == 'true'){
  67. GM_setValue(`${Name}`, false);
  68. GM_notification({text: `已关闭 [${Tips}] 功能${RefreshTips}`, timeout: 3500});
  69. }else{
  70. GM_setValue(`${Name}`, true);
  71. GM_notification({text: `已开启 [${Tips}] 功能${RefreshTips}`, timeout: 3500});
  72. }
  73. registerMenuCommand(); // 重新注册脚本菜单
  74. };
  75.  
  76. // 返回菜单值
  77. function menu_value(menuName) {
  78. for (let menu of menu_ALL) {
  79. if (menu[0] == menuName) {
  80. return menu[3]
  81. }
  82. }
  83. }
  84.  
  85.  
  86. if (window.top.location.pathname === '/u' || window.top.location.pathname.indexOf('account.php') > -1 || window.top.location.pathname.indexOf('mydisk.php') > -1) { // 后台页
  87. if (window.top.location.href != "https://pc.woozooo.com/mydisk.php") {
  88. window.top.location.href = "https://pc.woozooo.com/mydisk.php"
  89. }
  90. var mainframe;
  91. iframe();
  92. } else if (window.top.location.pathname.indexOf('%') > -1) { // 带密码的分享链接页面
  93. shareLinkWithPassword(); // 带密码的分享链接自动输密码
  94. } else {
  95. setTimeout(function() { // 延迟 300 毫秒(避免网页还没加载完)
  96. if (document.getElementById('infos')) { // 分享链接文件列表页
  97. if (document.getElementById('pwdload')) { // 分享链接输入密码页
  98. enterPassword(); // 自动输入密码(仅支持访问 带密码的分享链接 时)
  99. enterToPass(); // 输入密码后回车确认
  100. }
  101. fileMoreS(); // 自动显示更多文件
  102. }
  103. }, 300);
  104. }
  105.  
  106.  
  107. // 获取 iframe 框架
  108. function iframe() {
  109. mainframe = document.getElementById("mainframe");
  110. if(mainframe){ // 只有找到 iframe 框架时才会继续运行脚本
  111. mainframe = mainframe.contentWindow;
  112. if(menu_value('menu_refreshCorrection')){
  113. refreshCorrection(); // 刷新不返回根目录(F5)
  114. }
  115. setTimeout(folderDescdes, 200); // 调整话说编辑框初始大小
  116. setTimeout(hideSha, 200); // 隐藏分享链接窗口(这样自动打开/复制分享链接时,不会一闪而过)
  117. fobiddenBack(); // 禁止浏览器返回(并绑定新的返回事件)
  118. EventXMLHttpRequest(); // 监听 XMLHttpRequest 事件并执行 [自动显示更多文件]
  119.  
  120. dragEnter(); // 拖入文件自动显示上传框
  121. }
  122. }
  123.  
  124.  
  125. // 带密码的分享链接自动输密码
  126. function shareLinkWithPassword() {
  127. if (location.pathname.indexOf('%E5%AF%86%E7%A0%81') > -1) {
  128. let shareLink = location.pathname.split('%')
  129. if (shareLink.length > 0) {
  130. shareLink = location.origin + shareLink[0]
  131. let password = location.pathname.replace('%E5%AF%86%E7%A0%81',':').replace(/%([A-Z]|[0-9]){2}/ig, '').split(':')
  132. if (password.length > 0) {
  133. location.replace(shareLink + '?password=' + password[password.length - 1])
  134. }
  135. }
  136. }
  137. }
  138.  
  139.  
  140. // 自动输入密码(仅支持访问 带密码的分享链接 时)
  141. function enterPassword() {
  142. if (location.search.indexOf('?password=') > -1) {
  143. let password = location.search.split('=')
  144. if (password.length > 0) {
  145. document.getElementById('pwd').value = password[password.length - 1]
  146. document.getElementById('sub').click();
  147. }
  148. }
  149. }
  150.  
  151.  
  152. // 刷新不返回根目录(F5)
  153. function refreshCorrection() {
  154. document.onkeydown = mainframe.onkeydown = function (e) {
  155. e = window.event || e;
  156. let keycode = e.keyCode;
  157. if (keycode == 116) {
  158. e.keyCode = 0;
  159. let folderID = /-?\d+/.exec(mainframe.document.getElementById("filemore").children[0].getAttribute("onclick"))
  160. if(folderID.length > 0){
  161. mainframe.folder(folderID[0]);
  162. e.returnValue = false;
  163. e.cancelBubble = true;
  164. return false;
  165. }
  166. }
  167. }
  168. }
  169.  
  170.  
  171. // 恢复刷新机制
  172. function UNrefreshCorrection() {
  173. document.onkeydown = mainframe.onkeydown = function (e) {
  174. e = window.event || e;
  175. let keycode = e.keyCode;
  176. if (keycode == 116) {
  177. return true;
  178. }
  179. }
  180. }
  181.  
  182.  
  183. // 右键文件显示菜单
  184. function rightClickMenu() {
  185. if(menu_value('menu_rightClickMenu')){ // 脚本菜单开启时才继续
  186. rightClickMenu_("sub_folder_list", "fols", "folse") // 文件夹
  187. rightClickMenu_("filelist", "fs", "fse") // 文件
  188. }
  189. }
  190.  
  191.  
  192. // 右键文件显示菜单,参数:文件/文件夹列表 ID、菜单 ID 前缀
  193. function rightClickMenu_(list_id_name, menu_id_name_prefix, list_id_name_prefix) {
  194. let list_ = mainframe.document.getElementById(list_id_name);
  195. if(list_){ // 文件/文件夹列表
  196. list_.oncontextmenu = function(e){
  197. e.preventDefault(); // 屏蔽浏览器自身右键菜单
  198. let left = e.pageX - 30; // 右键菜单弹出位置
  199. let list_ID = e.target.id;
  200. if(e.target.nodeName == "FONT"){
  201. list_ID = e.target.parentNode.parentNode.id
  202. }else if(e.target.id == ""){
  203. list_ID = e.target.parentNode.id
  204. }
  205. list_ID = /\d+/.exec(list_ID)
  206. if(list_ID.length > 0){
  207. mainframe.document.getElementById(menu_id_name_prefix + list_ID[0]).style.cssText="position: absolute !important; left: " + left + "px;" // 修改右键菜单弹出位置(X)
  208. mainframe.document.getElementById(list_id_name_prefix + list_ID[0]).focus();
  209. mainframe.document.getElementById(list_id_name_prefix + list_ID[0]).click();
  210. }
  211. }
  212. }
  213. }
  214.  
  215.  
  216. // 自动显示更多文件(后台页)
  217. function fileMore() {
  218. let filemore = mainframe.document.getElementById("filemore"); // 寻找 [显示更多文件] 按钮
  219. if(filemore && filemore.style.display == "block"){ // 判断按钮是否存在且可见
  220. if(filemore.children[0]){ // 判断按钮元素下第一个元素是否存在
  221. filemore.children[0].click(); // 点击 [显示更多文件] 按钮
  222. }
  223. }
  224. }
  225.  
  226.  
  227. // 自动显示更多文件(分享链接列表页)
  228. function fileMoreS() {
  229. windowScroll(function (direction, e) {
  230. if (direction === "down") { // 下滑才准备加载更多
  231. let scrollTop = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop;
  232. let scrollDelta = 500;
  233. if (document.documentElement.scrollHeight <= document.documentElement.clientHeight + scrollTop + scrollDelta) {
  234. let filemore = document.getElementById("filemore"); // 寻找 [显示更多文件] 按钮
  235. if (filemore && filemore.style.display != "none") { // 如果正在加载,就不再点击
  236. if (filemore.innerText.indexOf('更多') > -1){ // 避免已经在加载了,重复点击
  237. filemore.click(); // 点击 [显示更多文件] 按钮
  238. }
  239. }
  240. }
  241. }
  242. });
  243. }
  244.  
  245.  
  246. // 滚动条事件
  247. function windowScroll(fn1) {
  248. var beforeScrollTop = document.documentElement.scrollTop,
  249. fn = fn1 || function () {};
  250. setTimeout(function () { // 延时执行,避免刚载入到页面就触发翻页事件
  251. window.addEventListener("scroll", function (e) {
  252. var afterScrollTop = document.documentElement.scrollTop,
  253. delta = afterScrollTop - beforeScrollTop;
  254. if (delta == 0) return false;
  255. fn(delta > 0 ? "down" : "up", e);
  256. beforeScrollTop = afterScrollTop;
  257. }, false);
  258. }, 1000)
  259. }
  260.  
  261.  
  262. // 调整话说编辑框初始大小
  263. function folderDescdes() {
  264. if(menu_value('menu_folderDescdesMenu')) {
  265. let folderdescdes = mainframe.document.getElementById("folder_descdes"); // 寻找话说(描述)编辑框
  266. if(folderdescdes){ // 判断话说(描述)元素是否存在
  267. folderdescdes.style.cssText="margin: 15px 0px; width: 550px; height: 125px;"
  268. }
  269. let folderdescdes2 = mainframe.document.getElementById("fol_credes"); // 寻找话说(描述)编辑框
  270. if(folderdescdes2){ // 判断话说(描述)元素是否存在
  271. folderdescdes2.style.cssText="margin: 15px 0px; width: 550px; height: 125px;"
  272. }
  273. let folderdescdes3 = mainframe.document.getElementById("file_desc"); // 寻找话说(描述)编辑框
  274. if(folderdescdes3){ // 判断话说(描述)元素是否存在
  275. folderdescdes3.style.cssText="margin: 15px 0px; width: 550px; height: 125px;"
  276. }
  277. }
  278. }
  279.  
  280.  
  281. // 拖入文件自动显示上传框
  282. function dragEnter() {
  283. mainframe.addEventListener("dragenter", function (e) {
  284. e.preventDefault();
  285. e.stopPropagation();
  286. let f_upb = mainframe.document.querySelector(".f_upb")
  287. if(f_upb.style.top != "-36px") {
  288. f_upb.style.top = "-36px";
  289. mainframe.f_upc();
  290. }
  291. }, false);
  292. mainframe.addEventListener("drop", function (e) {
  293. e.preventDefault();
  294. //e.stopPropagation();
  295. console.log('111111')
  296. //console.log(e.dataTransfer.files)
  297. });
  298. }
  299.  
  300.  
  301. // 分享链接相关(点击文件时)
  302. function fileSha() {
  303. var f_sha = mainframe.document.getElementById("f_sha"); // 寻找分享链接(下载链接)信息框
  304. if(f_sha && f_sha.style.display == "block"){ // 判断信息框是否存在且可见
  305. fileSha_Open(); // 自动打开分享链接(点击文件时)
  306. fileSha_Copy(); // 自动复制分享链接(点击文件时)
  307. if(menu_value('menu_open_fileSha') || menu_value('menu_copy_fileSha')){
  308. f_sha.style.display = "none"; // 隐藏分享链接(下载链接)信息框
  309. }
  310. }
  311. }
  312.  
  313.  
  314. // 自动打开分享链接(点击文件时)
  315. function fileSha_Open() {
  316. if(menu_value('menu_open_fileSha')){ // 脚本菜单开启时才继续
  317. let code = mainframe.document.getElementById("code").getAttribute("title"); // 获取分享链接(下载链接)
  318. if(code != ""){ // 确保分享链接(下载链接)不是空
  319. window.GM_openInTab(code, {active: true,insert: true,setParent: true}) // 打开分享链接(下载链接)
  320. }
  321. }
  322. }
  323.  
  324.  
  325. // 自动复制分享链接(点击文件时)
  326. function fileSha_Copy() {
  327. if(menu_value('menu_copy_fileSha')){ // 脚本菜单开启时才继续
  328. let f_sha1 = mainframe.document.getElementById("f_sha1").innerText; // 获取分享链接(下载链接)
  329. if(f_sha1 != ""){ // 确保分享链接(下载链接)不是空
  330. copyToClipboard(f_sha1); // 复制到剪切板
  331. }
  332. }
  333. }
  334.  
  335.  
  336. // 复制到剪切板
  337. function copyToClipboard(s){
  338. if(window.clipboardData){
  339. window.clipboardData.setData('text',s);
  340. }else{
  341. (function(s){
  342. document.oncopy=function(e){
  343. e.clipboardData.setData('text',s);
  344. e.preventDefault();
  345. document.oncopy=null;
  346. }
  347. })(s);
  348. document.execCommand('Copy');
  349. }
  350. }
  351.  
  352.  
  353. // 隐藏分享链接窗口(这样自动打开/复制分享链接时,不会一闪而过)
  354. function hideSha(){
  355. if(menu_value('menu_open_fileSha') || menu_value('menu_copy_fileSha')){ // [自动复制分享链接] 或 [自动打开分享链接] 任意一个功能开启时才继续
  356. let style_Add = mainframe.document.createElement('style');
  357. style_Add.type = 'text/css';
  358. style_Add.innerHTML = `#f_sha {display: none !important;}`;
  359. mainframe.document.head.appendChild(style_Add);
  360. }
  361. }
  362.  
  363.  
  364. // 禁止浏览器返回(并绑定新的返回事件)
  365. function fobiddenBack() {
  366. history.pushState(null, null, document.URL);
  367. window.addEventListener('popstate',backEvent)
  368. }
  369.  
  370.  
  371. // 允许浏览器返回
  372. function enableBack() {
  373. history.go(-1);
  374. window.removeEventListener('popstate',backEvent)
  375. }
  376.  
  377.  
  378. // 浏览器后退事件函数
  379. function backEvent() {
  380. if(lastFolderID) {
  381. mainframe.folder(lastFolderID);
  382. }
  383. history.pushState(null, null, document.URL);
  384. }
  385.  
  386.  
  387. // 获取上个文件夹 ID(用于浏览器后退事件)
  388. function getLastFolderID() {
  389. lastFolderID = null
  390. let f_tpspan = mainframe.document.querySelectorAll("span.f_tpspan");
  391. if(f_tpspan.length > 1) {
  392. lastFolderID = /-?\d+/.exec(f_tpspan[f_tpspan.length - 2].getAttribute("onclick"))[0];
  393. }
  394. }
  395.  
  396.  
  397. // 输入密码后回车确认
  398. function enterToPass() {
  399. document.getElementById('pwd').onkeydown = function(e){
  400. if(e.key === 'Enter'){
  401. document.getElementById('sub').click();
  402. }
  403. };
  404. }
  405.  
  406.  
  407. // 监听 XMLHttpRequest 事件并执行(新方法,只有在产生事件时才会执行 [自动显示更多文件],平时不会执行,更优雅~)
  408. function EventXMLHttpRequest() {
  409. var _send = mainframe.XMLHttpRequest.prototype.send
  410. function sendReplacement(data) {
  411. setTimeout(fileMore, 200); // 自动显示更多文件
  412. setTimeout(fileSha, 200); // 自动打开分享链接(点击文件时)
  413. setTimeout(rightClickMenu, 500); // 右键文件显示菜单
  414. setTimeout(getLastFolderID, 200); // 获取上个文件夹 ID(用于浏览器后退事件)
  415. return _send.apply(this, arguments);
  416. }
  417. mainframe.XMLHttpRequest.prototype.send = sendReplacement;
  418. }
  419.  
  420.  
  421. /*(function (open) {
  422. mainframe.XMLHttpRequest.prototype.open = function () {
  423. this.addEventListener("readystatechange", function () {
  424. if(this.responseURL != "") {
  425. console.log(this.responseURL);
  426. }
  427. }, false);
  428. open.apply(this, arguments);
  429. };
  430. })(mainframe.XMLHttpRequest.prototype.open);*/
  431. })();