蓝奏云网盘增强

文件排序、刷新不回根目录、快捷返回上一级(右键网页空白处)、后退返回上一级、右键文件显示菜单、点击直接下载文件、点击空白进入目录、自动显示更多文件、一键复制所有分享链接、自定义分享链接域名、自动打开/复制分享链接、带密码的分享链接自动输密码、拖入文件自动显示上传框、输入密码后回车确认、优化编辑框初始大小

安装此脚本?
作者推荐脚本

您可能也喜欢自动无缝翻页

安装此脚本
  1. // ==UserScript==
  2. // @name 蓝奏云网盘增强
  3. // @version 1.5.6
  4. // @author X.I.U
  5. // @description 文件排序、刷新不回根目录、快捷返回上一级(右键网页空白处)、后退返回上一级、右键文件显示菜单、点击直接下载文件、点击空白进入目录、自动显示更多文件、一键复制所有分享链接、自定义分享链接域名、自动打开/复制分享链接、带密码的分享链接自动输密码、拖入文件自动显示上传框、输入密码后回车确认、优化编辑框初始大小
  6. // @match *://lanzou.com/u
  7. // @match *://www.lanzou.com/u
  8. // @match *://www.lanzou.com/account.php*
  9. // @match *://up.woozooo.com/u
  10. // @match *://up.woozooo.com/mydisk.php*
  11. // @match *://pc.woozooo.com/u
  12. // @match *://pc.woozooo.com/mydisk.php*
  13. // @match *://pan.lanzou.com/*
  14. // @match *://*.lanzoub.com/*
  15. // @match *://*.lanzoue.com/*
  16. // @match *://*.lanzouf.com/*
  17. // @match *://*.lanzouh.com/*
  18. // @match *://*.lanzoui.com/*
  19. // @match *://*.lanzouj.com/*
  20. // @match *://*.lanzoul.com/*
  21. // @match *://*.lanzoum.com/*
  22. // @match *://*.lanzouo.com/*
  23. // @match *://*.lanzoup.com/*
  24. // @match *://*.lanzouq.com/*
  25. // @match *://*.lanzout.com/*
  26. // @match *://*.lanzouu.com/*
  27. // @match *://*.lanzouv.com/*
  28. // @match *://*.lanzouw.com/*
  29. // @match *://*.lanzoux.com/*
  30. // @match *://*.lanzouy.com/*
  31. // @match *://*.lanzob.com/*
  32. // @match *://*.lanzoe.com/*
  33. // @match *://*.lanzof.com/*
  34. // @match *://*.lanzoh.com/*
  35. // @match *://*.lanzoi.com/*
  36. // @match *://*.lanzoj.com/*
  37. // @match *://*.lanzol.com/*
  38. // @match *://*.lanzom.com/*
  39. // @match *://*.lanzoo.com/*
  40. // @match *://*.lanzop.com/*
  41. // @match *://*.lanzoq.com/*
  42. // @match *://*.lanzot.com/*
  43. // @match *://*.lanzov.com/*
  44. // @match *://*.lanzow.com/*
  45. // @match *://*.lanzox.com/*
  46. // @match *://*.lanzoy.com/*
  47. // @match *://*.lanzb.com/*
  48. // @match *://*.lanze.com/*
  49. // @match *://*.lanzf.com/*
  50. // @match *://*.lanzh.com/*
  51. // @match *://*.lanzi.com/*
  52. // @match *://*.lanzj.com/*
  53. // @match *://*.lanzl.com/*
  54. // @match *://*.lanzm.com/*
  55. // @match *://*.lanzo.com/*
  56. // @match *://*.lanzp.com/*
  57. // @match *://*.lanzq.com/*
  58. // @match *://*.lanzt.com/*
  59. // @match *://*.lanzv.com/*
  60. // @match *://*.lanzw.com/*
  61. // @match *://*.lanzx.com/*
  62. // @match *://*.lanzy.com/*
  63. // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABZ0lEQVR4nJ2TvW4UQRCEv+q9H8wGwFlIOEQQIRmnCIcnEidkSAQYEpwQIPEoZPgliB04IiW15JRXAMkne3e6COaMZe7HiEqmpzVV01PTLR9g1kIAGNdYQgrIAmliPfkSRghFQEk46yGB8S0GN3IF9fKAWYHJJjzbx0/30P1H/yBggwKfF9h5gfa/wObDeV6LAkYQDWTWq5shml3A9hR9+AqjFrLMnVkigECzHhqgEf51Affuotef8ahF2UNc0QZ/s9UZnr/Cu+/Q8DZ8O8TDDbT1pDof1ylXu2iqSdP38OYQ2VhCj3dh9rM+LhY/rQooII3bMUw/1veVrhIU0E5WehxWQILPEjRC7QQDbga1XKk6vgIDuoRxi/bews5LvHGnFqU/DXDZjMuRnx44T49t2860nc756rSzL/P8cpAnRzUqnV36hQOlO7ezrBRQ2pYLEFigtfUuMRHAiptGcrWAfnyvk/afEr8Bt+re7W42OSoAAAAASUVORK5CYII=
  64. // @grant GM_xmlhttpRequest
  65. // @grant GM_registerMenuCommand
  66. // @grant GM_unregisterMenuCommand
  67. // @grant GM_openInTab
  68. // @grant GM_getValue
  69. // @grant GM_setValue
  70. // @grant GM_notification
  71. // @grant GM_setClipboard
  72. // @grant unsafeWindow
  73. // @sandbox JavaScript
  74. // @noframes
  75. // @license GPL-3.0 License
  76. // @run-at document-end
  77. // @namespace https://github.com/XIU2/UserScript
  78. // @supportURL https://github.com/XIU2/UserScript
  79. // @homepageURL https://github.com/XIU2/UserScript
  80. // ==/UserScript==
  81.  
  82. (function() {
  83. 'use strict';
  84. var menu_ALL = [
  85. ['menu_customFileSha', '自定义分享链接域名', '自定义分享链接域名', ''],
  86. ['menu_open_fileSha', '自动打开分享链接', '自动打开分享链接', true],
  87. ['menu_copy_fileSha', '自动复制分享链接', '自动复制分享链接', true],
  88. ['menu_refreshCorrection', '刷新不返回根目录', '刷新不返回根目录', true],
  89. ['menu_rightClickMenu', '右键文件显示菜单', '右键文件显示菜单', true],
  90. ['menu_directDownload', '点击直接下载文件 (分享链接列表页)', '点击直接下载文件', true],
  91. ['menu_folderDescdesMenu', '优化编辑框初始大小', '优化编辑框初始大小', true],
  92. ['menu_fileSort', '文件排序', '文件排序', true]
  93. ], menu_ID = [], lastFolderID;
  94. for (let i=0;i<menu_ALL.length;i++){ // 如果读取到的值为 null 就写入默认值
  95. if (GM_getValue(menu_ALL[i][0]) == null){GM_setValue(menu_ALL[i][0], menu_ALL[i][3])};
  96. }
  97. registerMenuCommand();
  98.  
  99. // 注册(不可用)脚本菜单
  100. function registerMenuCommand() {
  101. if (menu_ID.length > menu_ALL.length){ // 如果菜单ID数组多于菜单数组,说明不是首次添加菜单,需要卸载所有脚本菜单
  102. for (let i=0;i<menu_ID.length;i++){
  103. GM_unregisterMenuCommand(menu_ID[i]);
  104. }
  105. }
  106. for (let i=0;i<menu_ALL.length;i++){ // 循环注册(不可用)脚本菜单
  107. menu_ALL[i][3] = GM_getValue(menu_ALL[i][0]);
  108. if (menu_ALL[i][0] == 'menu_refreshCorrection') {
  109. 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]}`)});
  110. } else if (menu_ALL[i][0] === 'menu_customFileSha') {
  111. menu_ID[i] = GM_registerMenuCommand(`#️⃣ ${menu_ALL[i][1]}`, function(){customFileSha()});
  112. } else {
  113. 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]}`)});
  114. }
  115. }
  116. 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://gf.qytechs.cn/zh-CN/scripts/419224/feedback', {active: true,insert: true,setParent: true});});
  117. }
  118.  
  119. // 菜单开关
  120. function menu_switch(menu_status, Name, Tips) {
  121. if (menu_status == 'true') {
  122. GM_setValue(`${Name}`, false);
  123. if (Name == 'menu_refreshCorrection') {
  124. GM_notification({text: `已关闭 [${Tips}] 功能`, timeout: 3500});
  125. } else {
  126. GM_notification({text: `已关闭 [${Tips}] 功能\n(点击刷新网页后生效)`, timeout: 3500, onclick: function(){location.reload();}});
  127. }
  128. } else {
  129. GM_setValue(`${Name}`, true);
  130. if (Name == 'menu_refreshCorrection') {
  131. GM_notification({text: `已开启 [${Tips}] 功能`, timeout: 3500});
  132. } else {
  133. GM_notification({text: `已开启 [${Tips}] 功能\n(点击刷新网页后生效)`, timeout: 3500, onclick: function(){location.reload();}});
  134. }
  135. }
  136. registerMenuCommand(); // 重新注册(不可用)脚本菜单
  137. };
  138.  
  139. // 返回菜单值
  140. function menu_value(menuName) {
  141. for (let menu of menu_ALL) {
  142. if (menu[0] == menuName) {
  143. return menu[3]
  144. }
  145. }
  146. }
  147.  
  148.  
  149. if (window.top.location.pathname === '/u' || window.top.location.pathname.indexOf('account.php') > -1 || window.top.location.pathname.indexOf('mydisk.php') > -1) { // 后台页
  150. if (window.top.location.href != 'https://pc.woozooo.com/mydisk.php') window.top.location.href = 'https://pc.woozooo.com/mydisk.php';
  151. RememberLoginStatus() // 通过延长 cookie 到期时间来一直记住登录(不可用)状态
  152. var mainframe;
  153. iframe();
  154. } else if (window.top.location.pathname.indexOf('%') > -1) { // > 带密码的分享链接页面
  155. shareLinkWithPassword(); // 带密码的分享链接自动输密码
  156. } else {
  157. setTimeout(function() { // 延迟 300 毫秒(避免网页还没加载完)
  158. if (document.querySelector('#pwdload,#passwddiv')) { // > 分享链接输入密码页
  159. enterPassword(); // 自动输入密码(仅支持访问 带密码的分享链接 时)
  160. enterToPass(); // 输入密码后回车确认(针对手动输入密码)
  161. }
  162. if (document.getElementById('infos')) { // > 分享链接文件列表页
  163. fileMoreS(); // 自动显示更多文件
  164. directDownload(); // 点击直接下载文件(分享链接列表页)
  165. }
  166. }, 300);
  167. directDownload_(); // 点击直接下载文件(分享链接列表页)
  168. }
  169.  
  170.  
  171. // 获取 iframe 框架
  172. function iframe() {
  173. mainframe = document.getElementById('mainframe');
  174. if (mainframe) { // 只有找到 iframe 框架时才会继续运行脚本
  175. mainframe = mainframe.contentWindow;
  176. if (menu_value('menu_refreshCorrection')) refreshCorrection(); // 刷新不返回根目录(F5)
  177. setTimeout(folderDescdes, 500); // 优化编辑框初始大小
  178. setTimeout(hideSha, 500); // 隐藏分享链接窗口(这样自动打开/复制分享链接时,不会一闪而过)
  179. fobiddenBack(); // 禁止浏览器返回(并绑定新的返回事件)
  180. EventXMLHttpRequest(); // 监听 XMLHttpRequest 事件并执行 [自动显示更多文件]
  181. setTimeout(clickOpenDirectory, 500); // 点击空白进入目录
  182. setTimeout(backToTop, 2000); // 快捷返回上级(右键点击 网页右侧/下方 空白处)
  183.  
  184. dragEnter(); // 拖入文件自动显示上传框
  185. setTimeout(viewTop,1000); // 监听并修改右键菜单 [外链分享地址] 为 [复制并打开分享链接] / [复制分享链接] / [打开分享链接] 之一
  186. setTimeout(copyAllfileSha, 500); // 一键复制所有分享链接
  187.  
  188. setTimeout(filesSort, 300); // 文件排序
  189. }
  190. }
  191.  
  192.  
  193. // 带密码的分享链接自动输密码
  194. function shareLinkWithPassword() {
  195. if (location.pathname.indexOf('%E5%AF%86%E7%A0%81') > -1) {
  196. let shareLink = location.pathname.split('%')
  197. if (shareLink.length > 0) {
  198. shareLink = location.origin + shareLink[0]
  199. let password = location.pathname.replace('%E5%AF%86%E7%A0%81',':').replace(/%([A-Z]|[0-9]){2}/ig, '').split(':')
  200. if (password.length > 0) {
  201. location.replace(shareLink + '?pwd=' + password[password.length - 1])
  202. }
  203. }
  204. }
  205. }
  206.  
  207.  
  208. // 自动输入密码(仅支持访问 带密码的分享链接 时,比如上面 [带密码的分享链接自动输密码] 功能重定向后的链接)
  209. function enterPassword() {
  210. if (location.search.indexOf('?pwd=') > -1 || location.search.indexOf('?passwd=') > -1 || location.search.indexOf('?password=') > -1) {
  211. let password = location.search.split('=')
  212. if (password.length > 0) {
  213. document.getElementById('pwd').value = password[password.length - 1]
  214. if (document.getElementById('sub')) {
  215. document.getElementById('sub').click();
  216. } else {
  217. document.querySelector('.passwddiv-btn[onclick]').click();
  218. }
  219. }
  220. }
  221. }
  222.  
  223.  
  224. // 刷新不返回根目录(F5)
  225. function refreshCorrection() {
  226. document.onkeydown = mainframe.onkeydown = function (e) {
  227. e = window.event || e;
  228. if (e.key === 'F5') {
  229. let folderID = /-?\d+/.exec(mainframe.document.getElementById('filemore').children[0].onclick)
  230. if(folderID.length > 0){
  231. mainframe.folder(folderID[0]);
  232. e.returnValue = false;
  233. e.cancelBubble = true;
  234. return false;
  235. }
  236. }
  237. }
  238. }
  239.  
  240.  
  241. // 恢复刷新机制
  242. function UNrefreshCorrection() {
  243. document.onkeydown = mainframe.onkeydown = function (e) {
  244. e = window.event || e;
  245. if (e.key === 'F5') {
  246. return true;
  247. }
  248. }
  249. }
  250.  
  251.  
  252. // 点击空白进入目录
  253. function clickOpenDirectory() {
  254. mainframe.document.getElementById('sub_folder_list').onclick = function(e){
  255. //console.log(e.target);
  256. if (e.target.className && e.target.className == 'f_tb') {
  257. e.target.querySelector('span.follink').click()
  258. }
  259. }
  260. }
  261.  
  262.  
  263. // 右键文件显示菜单
  264. function rightClickMenu() {
  265. if (!menu_value('menu_rightClickMenu')) return
  266. rightClickMenu_('sub_folder_list', 'fols', 'folse') // 文件夹
  267. rightClickMenu_('filelist', 'fs', 'fse') // 文件
  268. }
  269.  
  270.  
  271. // 右键文件显示菜单,参数:文件/文件夹列表 ID、菜单 ID、菜单 ID前缀
  272. function rightClickMenu_(list_id_name, menu_id_name_prefix, list_id_name_prefix) {
  273. let list_ = mainframe.document.getElementById(list_id_name);
  274. if (!list_) return // 文件/文件夹列表
  275. list_.oncontextmenu = function(e){
  276. e.preventDefault(); // 屏蔽浏览器自身右键菜单
  277. let left = e.pageX - 30; // 右键菜单弹出位置
  278. let list_ID = e.target.id;
  279. if (e.target.nodeName === 'FONT') {
  280. list_ID = e.target.parentNode.parentNode.id
  281. } else if(e.target.id === '') {
  282. list_ID = e.target.parentNode.id
  283. }
  284. list_ID = /\d+/.exec(list_ID)
  285. if(list_ID.length > 0){
  286. mainframe.document.getElementById(menu_id_name_prefix + list_ID[0]).style.cssText='position: absolute !important; left: ' + left + 'px;' // 修改右键菜单弹出位置(X)
  287. mainframe.document.getElementById(list_id_name_prefix + list_ID[0]).focus();
  288. mainframe.document.getElementById(list_id_name_prefix + list_ID[0]).click();
  289. }
  290. }
  291. }
  292.  
  293.  
  294. // 自动显示更多文件(后台页)
  295. function fileMore() {
  296. let filemore = mainframe.document.getElementById('filemore'); // 寻找 [显示更多文件] 按钮
  297. if (filemore && filemore.style.display === 'block') { // 判断按钮是否存在且可见
  298. if (filemore.children[0]) { // 判断按钮元素下第一个元素是否存在
  299. filemore.children[0].click(); // 点击 [显示更多文件] 按钮
  300. }
  301. }
  302. }
  303.  
  304.  
  305. // 自动显示更多文件(分享链接列表页)
  306. function fileMoreS() {
  307. windowScroll(function (direction, e) {
  308. if (direction === 'down') { // 下滑才准备加载更多
  309. let scrollTop = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop;
  310. let scrollDelta = 500;
  311. if (document.documentElement.scrollHeight <= document.documentElement.clientHeight + scrollTop + scrollDelta) {
  312. let filemore = document.getElementById('filemore'); // 寻找 [显示更多文件] 按钮
  313. if (filemore && filemore.style.display != 'none') { // 如果正在加载,就不再点击
  314. if (filemore.textContent.indexOf('更多') > -1){ // 避免已经在加载了,重复点击
  315. filemore.click(); // 点击 [显示更多文件] 按钮
  316. }
  317. }
  318. }
  319. }
  320. });
  321. }
  322.  
  323.  
  324. // 点击直接下载文件(分享链接列表页)
  325. function directDownload() {
  326. if (!menu_value('menu_directDownload')) return
  327. if (document.getElementById('infos')) {
  328. document.getElementById('infos').addEventListener('click', function(e) {
  329. if (e.target.tagName === 'A') { // 针对普通样式的分享链接列表页
  330. e.preventDefault(); // 阻止默认打开链接事件
  331. GM_openInTab(e.target.href + '#download', {active: false, insert: true, setParent: true}); // 后台打开
  332. } else { // 针对会员专属样式的分享链接列表页
  333. const link = e.target.closest('a'); // 点击 <a> 元素的子元素时,寻找最近的 <a> 父元素
  334. if ((link && this.contains(link))) {
  335. e.preventDefault(); // 阻止默认打开链接事件
  336. GM_openInTab(link.href + '#download', {active: false, insert: true, setParent: true}); // 后台打开
  337. }
  338. }
  339. });
  340. }
  341. }
  342. // 点击下载按钮
  343. function directDownload_() {
  344. if (!menu_value('menu_directDownload')) return
  345. if (location.hash != '#download') return
  346. let iframe = document.querySelector('iframe.ifr2, iframe.n_downlink');
  347. if (iframe) { // 只有找到 iframe 框架时才会继续运行脚本
  348. iframe = iframe.contentWindow;
  349. let timer = setInterval(function(){
  350. if (iframe.document.querySelector('.load>[href]')) {
  351. //iframe.document.querySelector('.load>a[href]').target = '_top'
  352. //iframe.document.querySelector('.load>a[href]').click();
  353. GM_openInTab(iframe.document.querySelector('.load>a[href]').href, {active: false, insert: true, setParent: false}); // 后台打开
  354. clearInterval(timer);
  355. // 关闭该后台标签页
  356. if (GM_info.scriptHandler === 'Violentmonkey') { // Violentmonkey 需要延迟一会儿
  357. setTimeout(function(){window.top.close();}, 500)
  358. } else {
  359. window.top.close();
  360. }
  361. }
  362. }, 10);
  363. }
  364. }
  365.  
  366.  
  367. // 滚动条事件
  368. function windowScroll(fn1) {
  369. var beforeScrollTop = document.documentElement.scrollTop,
  370. fn = fn1 || function () {};
  371. setTimeout(function () { // 延时执行,避免刚载入到页面就触发翻页事件
  372. window.addEventListener('scroll', function (e) {
  373. var afterScrollTop = document.documentElement.scrollTop,
  374. delta = afterScrollTop - beforeScrollTop;
  375. if (delta == 0) return false;
  376. fn(delta > 0 ? 'down' : 'up', e);
  377. beforeScrollTop = afterScrollTop;
  378. }, false);
  379. }, 1000)
  380. }
  381.  
  382.  
  383. // 优化编辑框初始大小
  384. function folderDescdes() {
  385. if (!menu_value('menu_folderDescdesMenu')) return
  386. mainframe.document.lastChild.appendChild(mainframe.document.createElement('style')).textContent = `#folder_descdes, #fol_credes, #file_desc {margin: 15px 0px; width: 550px; height: 125px;} input#f_ename_new {min-width: 700px; font-size: 14px;} #f_ename {z-index: 999;left: 15px;}`
  387. }
  388.  
  389.  
  390. // 拖入文件自动显示上传框
  391. function dragEnter() {
  392. mainframe.addEventListener('dragenter', function (e) {
  393. e.preventDefault();
  394. e.stopPropagation();
  395. let f_upb = mainframe.document.querySelector('.f_upb')
  396. if(f_upb.style.top != '-36px') {
  397. f_upb.style.top = '-36px';
  398. mainframe.f_upc();
  399. }
  400. }, false);
  401. mainframe.addEventListener('drop', function (e) {
  402. e.preventDefault();
  403. //e.stopPropagation();
  404. //console.log(e.dataTransfer.files)
  405. });
  406. }
  407.  
  408.  
  409. // 一键复制所有分享链接
  410. function copyAllfileSha() {
  411. var f_data = '', tmep_data = [];
  412. let f_tp = mainframe.document.getElementById('f_tp');
  413. //console.log(f_tp, mainframe.document.location.href)
  414. f_tp.insertAdjacentHTML('afterend', `<a id="f_copyAll" class="f_sela" style="float: right; width: auto; font-size: 12px !important; font: inherit; padding: 2px 10px; margin-top: -25px;" title="获取所有分享链接需要一些时间(取决于有多少文件)。&#10;因为分享链接没有显示在网页上,需要通过网页接口获取,因此为了避免太频繁被限制,所以设置了 300ms 间隔时间!">一键复制所有分享链接</a>`);
  415. mainframe.document.getElementById('f_copyAll').onclick = function() {
  416. f_data = ''; tmep_data = [];
  417. mainframe.document.querySelectorAll('.f_tb').forEach(function (_this) {
  418. //console.log(_this, _this.id.indexOf('fol') > -1)
  419. if (_this.id.indexOf('fol') > -1) {
  420. //console.log(`task=18&folder_id=${_this.id.replace('fol','')}`)
  421. tmep_data.push([`${_this.querySelector('span[id^="folname"]').textContent}`, `task=18&folder_id=${_this.id.replace('fol','')}`])
  422. } else {
  423. //console.log(`task=22&file_id=${_this.id.replace('f','')}`)
  424. tmep_data.push([`${_this.querySelector('span[id^="filename"]').textContent}`, `task=22&file_id=${_this.id.replace('f','')}`])
  425. }
  426. })
  427. //console.log(tmep_data)
  428. if (tmep_data.length > 0) {
  429. getUrl(0);
  430. GM_notification({text: '获取所有分享链接需要一些时间(取决于有多少文件),在此期间请不要关闭网页!', timeout: 5000});
  431. }
  432. };
  433.  
  434.  
  435. function getUrl(i) {
  436. //console.log(i)
  437. GM_xmlhttpRequest({
  438. url: 'https://pc.woozooo.com/doupload.php',
  439. method: 'POST',
  440. data: tmep_data[i][1],
  441. responseType: 'json',
  442. overrideMimeType: 'application/json; charset=utf-8',
  443. headers: {
  444. 'Referer': mainframe.document.location.href,
  445. 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
  446. },
  447. timeout: 5000,
  448. onload: function (response) {
  449. try {
  450. //console.log('返回内容:',response.response)
  451. if (response.response && response.response.zt === 1) {
  452. //console.log(response.response)
  453. if (response.response.info.f_id) {
  454. //console.log('文件 1',f_data)
  455. f_data += `${tmep_data[i][0]} `
  456. if (menu_value('menu_customFileSha')) {
  457. f_data += `https://${menu_value('menu_customFileSha')}/${response.response.info.f_id} `
  458. } else {
  459. f_data += `${response.response.info.is_newd}/${response.response.info.f_id} `
  460. }
  461. if (response.response.info.onof == '1') f_data += `密码:${response.response.info.pwd}`
  462. f_data += `\n`
  463. //console.log('文件 2',f_data)
  464. } else {
  465. //console.log('目录 1',f_data)
  466. f_data += `${response.response.info.name} `
  467. if (menu_value('menu_customFileSha')) {
  468. f_data += `${response.response.info.new_url.replace(/\/\/.+\//i, '//' + menu_value('menu_customFileSha') + '/')} `
  469. } else {
  470. f_data += `${response.response.info.new_url} `
  471. }
  472. if (response.response.info.onof == '1') f_data += `密码:${response.response.info.pwd}`
  473. f_data += `\n`
  474. //console.log('目录 2',f_data)
  475. }
  476. if (++i < tmep_data.length) {
  477. setTimeout(function(){getUrl(i);}, 300);
  478. } else {
  479. console.log(f_data)
  480. GM_setClipboard(f_data, 'text');
  481. GM_notification({text: '✅ 已复制所有文件/目录的分享链接到剪切板~', timeout: 2000});
  482. }
  483. } else {
  484. GM_notification({text: '❌ 更新失败,请联系作者解决...', timeout: 5000});
  485. }
  486. } catch (e) {
  487. console.log(e);
  488. }
  489. }
  490. })
  491. }
  492. }
  493.  
  494. // 分享链接相关(点击文件时)
  495. function fileSha() {
  496. var f_sha = mainframe.document.getElementById('f_sha'); // 寻找分享链接(下载链接)信息框
  497. if (f_sha && f_sha.style.display === 'block') { // 判断信息框是否存在且可见
  498. let f_sha1 = mainframe.document.getElementById('f_sha1'); // 获取分享链接(下载链接)
  499. if (f_sha1 && f_sha1.textContent != '') { // 确保分享链接(下载链接)不是空
  500. // 自定义分享链接域名
  501. if (menu_value('menu_customFileSha')) {f_sha1.innerText = f_sha1.innerText.replace(/\/\/.+\//i, '//' + menu_value('menu_customFileSha') + '/');}
  502. // 打开分享链接
  503. if (menu_value('menu_open_fileSha')) {f_sha.style.display = 'none';GM_openInTab(f_sha1.textContent, {active: true,insert: true,setParent: true});}
  504. // 复制分享链接(并已复制的提示信息)
  505. if (menu_value('menu_copy_fileSha')) {f_sha.style.display = 'none';GM_setClipboard(f_sha1.textContent, 'text');GM_notification({text: '已复制分享链接~', timeout: 2000});}
  506. // 直接下载文件
  507. //if (menu_value('menu_directDownload')) {f_sha.style.display = 'none';GM_openInTab(f_sha1.textContent + '#download', {active: false,insert: true,setParent: true});}
  508. }
  509. }
  510. }
  511.  
  512.  
  513. // 自定义分享链接域名
  514. function customFileSha() {
  515. let newDomain = prompt('请输入 [自定义分享链接域名],点击确定后立即生效\n蓝奏云分享链接末尾的 ID 是唯一的,而前面的域名用谁的都一样\n示例:pan.lanzoui.com 或 wwe.lanzoui.com 或 xiu.lanzoui.com', GM_getValue('menu_customFileSha'));
  516. if (newDomain === '') {
  517. GM_setValue('menu_customFileSha', '');
  518. registerMenuCommand(); // 重新注册(不可用)脚本菜单
  519. } else if (newDomain != null) {
  520. GM_setValue('menu_customFileSha', newDomain);
  521. registerMenuCommand(); // 重新注册(不可用)脚本菜单
  522. }
  523. }
  524.  
  525.  
  526. // 隐藏分享链接窗口(这样自动打开/复制分享链接时,不会一闪而过)
  527. function hideSha(){
  528. if (menu_value('menu_open_fileSha') || menu_value('menu_copy_fileSha')) { // [自动复制分享链接] 或 [自动打开分享链接] 任意一个功能开启时才继续
  529. mainframe.document.lastElementChild.appendChild(document.createElement('style')).textContent = '#f_sha {display: none !important;}';
  530. }
  531. }
  532.  
  533.  
  534. // 禁止浏览器返回(并绑定新的返回事件)
  535. function fobiddenBack() {
  536. history.pushState(null, null, document.URL);
  537. window.addEventListener('popstate',backEvent)
  538. }
  539.  
  540.  
  541. // 允许浏览器返回
  542. function enableBack() {
  543. history.go(-1);
  544. window.removeEventListener('popstate',backEvent)
  545. }
  546.  
  547.  
  548. // 浏览器后退事件函数
  549. function backEvent() {
  550. if (lastFolderID) {
  551. mainframe.folder(lastFolderID);
  552. }
  553. history.pushState(null, null, document.URL);
  554. }
  555.  
  556.  
  557. // 获取上个文件夹 ID(用于浏览器后退事件)
  558. function getLastFolderID() {
  559. lastFolderID = null
  560. let f_tpspan = mainframe.document.querySelectorAll('span.f_tpspan');
  561. if (f_tpspan.length > 1) {
  562. lastFolderID = /-?\d+/.exec(f_tpspan[f_tpspan.length - 2].getAttribute('onclick'))[0];
  563. }
  564. }
  565.  
  566.  
  567. // 输入密码后回车确认
  568. function enterToPass() {
  569. document.getElementById('pwd').onkeydown = function(e){
  570. if (e.key === 'Enter') {
  571. document.getElementById('sub').click();
  572. }
  573. };
  574. }
  575.  
  576.  
  577. // 快捷返回上级(右键点击 网页右侧/下方 空白处)
  578. function backToTop() {
  579. mainframe.document.getElementById('container').oncontextmenu = mainframe.document.body.oncontextmenu = function(e){
  580. if (e.target == this) {
  581. e.preventDefault();
  582. backEvent();
  583. }
  584. }
  585. }
  586.  
  587.  
  588. // 监听 XMLHttpRequest 事件并执行
  589. function EventXMLHttpRequest() {
  590. var _send = mainframe.XMLHttpRequest.prototype.send
  591. function sendReplacement(data) {
  592. setTimeout(fileMore, 200); // 自动显示更多文件
  593. setTimeout(fileSha, 200); // 自动打开分享链接(点击文件时)
  594. setTimeout(rightClickMenu, 500); // 右键文件显示菜单
  595. setTimeout(getLastFolderID, 200); // 获取上个文件夹 ID(用于浏览器后退事件)
  596. return _send.apply(this, arguments);
  597. }
  598. mainframe.XMLHttpRequest.prototype.send = sendReplacement;
  599. }
  600.  
  601.  
  602. // 监听并修改右键菜单 [外链分享地址] 为 [复制并打开分享链接] / [复制分享链接] / [打开分享链接] 之一
  603. function viewTop() {
  604. const callback = (mutationsList, observer) => {
  605. for (const mutation of mutationsList) {
  606. for (const target of mutation.addedNodes) {
  607. if (target.nodeType != 1) return
  608. if (target.className === 'f_view') {
  609. //console.log(target)
  610. let f_viewtop = target.querySelector('.f_viewtop');
  611. if (f_viewtop && f_viewtop.textContent === '外链分享地址') {
  612. if (menu_value('menu_open_fileSha') && menu_value('menu_copy_fileSha')) {
  613. f_viewtop.textContent = '复制并打开分享链接';
  614. } else if (menu_value('menu_open_fileSha')) {
  615. f_viewtop.textContent = '打开分享链接';
  616. } else if (menu_value('menu_copy_fileSha')) {
  617. f_viewtop.textContent = '复制分享链接';
  618. }
  619. }
  620. }
  621. }
  622. }
  623. };
  624. const observer = new MutationObserver(callback);
  625. observer.observe(mainframe.document, { childList: true, subtree: true });
  626. }
  627.  
  628. // 通过延长 cookie 到期时间来一直记住登录(不可用)状态
  629. function RememberLoginStatus() {
  630. // 获取 Cookie
  631. function getCookie(name) {
  632. if (!name) return ''
  633. let arr = document.cookie.split(';');
  634. name += '=';
  635. for (let i=0; i<arr.length; i++) {let now = arr[i].trim();if (now.indexOf(name) == 0) return now.substring(name.length, now.length);}
  636. return '';
  637. }
  638.  
  639. const ylogin = getCookie('ylogin'), phpdisk_info = getCookie('phpdisk_info')
  640. if (ylogin !== '' && phpdisk_info !== '') { // 如果已登录(不可用)(有相应 cookie),那么就延长至浏览器支持的到期时间上限(不同浏览器对到期时间的限制不一样,一般是 1-5 年)
  641. document.cookie='ylogin=' + ylogin + '; domain=.woozooo.com; expires=Thu, 18 Dec 2099 12:00:00 GMT; path=/'
  642. document.cookie='phpdisk_info=' + phpdisk_info + '; domain=pc.woozooo.com; expires=Thu, 18 Dec 2099 12:00:00 GMT; path=/'
  643. }
  644. }
  645.  
  646. // 文件排序
  647. function filesSort() {
  648. const frame = mainframe;
  649. const frameDoc = frame.document;
  650.  
  651. const currentStatus = {
  652. by: 'name',
  653. order: 'asc',
  654. }
  655.  
  656. let allButtons = undefined;
  657.  
  658. // 文件名排序
  659. function sortByName(name1, name2) {
  660. function sort(a, b) {
  661. const strA = a.toLocaleLowerCase().split('');
  662. const strB = b.toLocaleLowerCase().split('');
  663. for (let i = 0; i < strA.length; i++) {
  664. if (strA[i] === strB[i]) {
  665. continue;
  666. }
  667. if (strB[i] === undefined) return 1;
  668. if (notChinese(strA[i]) && notChinese(strB[i])) {
  669. return strA[i] < strB[i] ? -1 : 1;
  670. } else if (notChinese(strA[i])) {
  671. return -1;
  672. } else if (notChinese(strB[i])) {
  673. return 1;
  674. } else {
  675. return strA[i].localeCompare(strB[i]);
  676. }
  677. }
  678. if (strA.length === strB.length) {
  679. return 0;
  680. } else if (strA.length < strB.length) {
  681. return -1;
  682. }
  683. return 1;
  684. }
  685. function notChinese(char) {
  686. const charCode = char.charCodeAt(0)
  687. return charCode >= 0 && charCode <= 128
  688. }
  689. return sort(name1, name2);
  690. }
  691.  
  692. // 创建排序按鈕
  693. function createAllButtons() {
  694. const tabTitle = frameDoc.querySelector('#container > div.n1 > div.f_th');
  695. const name = tabTitle.querySelector('div.f_name');
  696. const size = tabTitle.querySelector('div.f_size');
  697. const time = tabTitle.querySelector('div.f_time');
  698. const down = tabTitle.querySelector('div.f_down'); // 下载量
  699. return {
  700. name: {
  701. el: createButton(name, 'name', '按 文件名称 排序'),
  702. order: 'asc',
  703. },
  704. size: {
  705. el: createButton(size, 'size', '按 文件大小 排序'),
  706. order: 'asc',
  707. },
  708. time: {
  709. el: createButton(time, 'time', '按 上传时间 排序'),
  710. order: 'asc',
  711. },
  712. down: {
  713. el: createButton(down, 'down', '按 下载次数 排序'),
  714. order: 'asc',
  715. }
  716. };
  717. }
  718. function createButton(element, by, title) {
  719. // element.insertAdjacentHTML('beforeend', '<a class="col_sort_btn" href="javascript: void;" style="font-size: 16px; float: right;">⇧</a>');
  720. let button = frameDoc.createElement('a');
  721. button.className = 'col_sort_btn';
  722. button.href = 'javascript: void(0);';
  723. button.style.fontSize = '16px';
  724. button.style.float = 'right';
  725. if (by == 'name') {button.style.float = 'left';}
  726. button.title = title;
  727. button.textContent = '⇧';
  728. button.onclick = () => clickSortButton(by, button);
  729. element.appendChild(button);
  730. return button;
  731. }
  732.  
  733.  
  734. function getFiles() {
  735. const list = frameDoc.querySelector('#filelist');
  736. const files = list.childNodes;
  737. const filesInfo = [];
  738. const now = new Date();
  739. for (const file of files) {
  740. const name = file.querySelector('.f_name > span.aspanlink > .f_name_title').textContent;
  741. const size = parseByteSize(file.querySelector('.f_size').textContent);
  742. const time = file.querySelector('.f_time').textContent;
  743. const down = parseInt(file.querySelector('.f_down').textContent);
  744. filesInfo.push({
  745. info: {
  746. name: name,
  747. size: size,
  748. time: parseTime(now, time),
  749. down: down
  750. },
  751. node: file
  752. })
  753. }
  754. return filesInfo;
  755. }
  756.  
  757. function getFolders() {
  758. const list = frameDoc.querySelector('#sub_folder_list');
  759. const folders = list.childNodes;
  760. const foldersInfo = [];
  761. for (const folder of folders) {
  762. const name = folder.querySelector('.f_tb > .f_name2 > span.follink > span').textContent;
  763. foldersInfo.push({
  764. info: {
  765. name: name,
  766. },
  767. node: folder
  768. })
  769. }
  770. return foldersInfo;
  771. }
  772. // 转换文件大小
  773. function parseByteSize(text) {
  774. const unit = ['B', 'K', 'M', 'G', 'T'];
  775. let size = 0;
  776. for (let i = 0; i < unit.length; i++) {
  777. if (text.indexOf(unit[i]) > -1) {
  778. size = parseFloat(text.replace(unit[i], '')) * Math.pow(1024, i);
  779. break;
  780. }
  781. }
  782. return size;
  783. }
  784. // 转换时间格式
  785. function parseTime(now, text) {
  786. function parseDay(time) {
  787. const days = [
  788. {
  789. name: '前天',
  790. offset: -2,
  791. },
  792. {
  793. name: '昨天',
  794. offset: -1,
  795. }
  796. ];
  797. const date = new Date(now.getTime());
  798. let index = -1;
  799. for (let i = 0; i < days.length; i++) {
  800. if (time.indexOf(days[i].name) > -1) {
  801. index = i;
  802. break;
  803. }
  804. }
  805. if (index === -1) return new Date(now.getTime());
  806. const hourAndMinute = text.replace(days[index].name, '').split(':');
  807. const hour = parseInt(hourAndMinute[0]);
  808. const minute = parseInt(hourAndMinute[1]);
  809. date.setDate(date.getDate() + days[index].offset);
  810. date.setHours(hour);
  811. date.setMinutes(minute);
  812. // 蓝奏云显示比较奇怪,超过24小时,未满48小时,都是昨天,并不以每天0点作为分界
  813. if (hour * 60 + minute > now.getHours() * 60 + now.getMinutes()) {
  814. date.setDate(date.getDate() - 1);
  815. }
  816. return date;
  817. }
  818. if (text.indexOf('秒前') > -1) {
  819. return now.getTime() - parseInt(text.replace('秒前', '')) * 1000;
  820. } else if (text.indexOf('分钟前') > -1) {
  821. return now.getTime() - parseInt(text.replace('分钟前', '')) * 60 * 1000;
  822. } else if (text.indexOf('小时前') > -1) {
  823. return now.getTime() - parseInt(text.replace('小时前', '')) * 60 * 60 * 1000;
  824. } else if (text.indexOf('昨天') > -1 || text.indexOf('前天') > -1) {
  825. return parseDay(text).getTime();
  826. } else if (text.indexOf('天前') > -1) {
  827. return now.getTime() - parseInt(text.replace('天前', '')) * 24 * 60 * 60 * 1000;
  828. } else if (text.indexOf('月前') > -1) { // 我不知道有没有以下几种情况,暂时先写上
  829. return now.getTime() - parseInt(text.replace('月前', '')) * 30 * 24 * 60 * 60 * 1000;
  830. } else if (text.indexOf('年前') > -1) {
  831. return now.getTime() - parseInt(text.replace('年前', '')) * 365 * 24 * 60 * 60 * 1000;
  832. }
  833. return Date.parse(text);
  834. }
  835.  
  836. // 排序
  837. function sortItems(files, by, order) {
  838. let compareFunc;
  839. if (by === 'name') {
  840. compareFunc = (a, b) => {
  841. return (order === 'asc' ? 1 : -1) * sortByName(a.info.name, b.info.name);
  842. }
  843. } else {
  844. compareFunc = (a, b) => {
  845. const result = a.info[by] > b.info[by] ? 1 : -1;
  846. return (order === 'asc' ? 1 : -1) * result;
  847. }
  848. }
  849. files.sort(compareFunc);
  850. }
  851.  
  852. function sortFileList() {
  853. const files = getFiles();
  854. if (files.length > 0) {
  855. sortItems(files, currentStatus.by, currentStatus.order);
  856. // console.log(files)
  857. const fileList = frameDoc.querySelector('#filelist');
  858. for (let i = 0; i < files.length; i++) {
  859. fileList.appendChild(files[i].node);
  860. }
  861. }
  862. }
  863.  
  864. function sortFolderList() {
  865. const folders = getFolders();
  866. // console.log(folders);
  867. if (folders.length > 0) {
  868. // 文件夹只能按名称排序
  869. if (currentStatus.by === 'name') {
  870. sortItems(folders, 'name', currentStatus.order);
  871. } else {
  872. sortItems(folders, 'name', 'asc'); // 其他情况,皆按名称升序
  873. }
  874. const folderList = frameDoc.querySelector('#sub_folder_list');
  875. for (let i = 0; i < folders.length; i++) {
  876. folderList.appendChild(folders[i].node);
  877. }
  878. }
  879. }
  880.  
  881. function fileListCallback(records) {
  882. if (!menu_value('menu_fileSort')) return;
  883. for (const event of records) {
  884. // 自己修改的时候不排序
  885. if (event.removedNodes.length > 0) return;
  886. }
  887. sortFileList();
  888. }
  889.  
  890. function folderListCallback(records) {
  891. if (!menu_value('menu_fileSort')) return;
  892. for (const event of records) {
  893. // 自己修改的时候不排序
  894. if (event.removedNodes.length > 0) return;
  895. }
  896. sortFolderList();
  897. }
  898.  
  899. function clickSortButton(by, button) {
  900. if (currentStatus.by === by) {
  901. // 当前选项,点击时,反转排序
  902. currentStatus.order = button.textContent === '⬆' ? 'desc' : 'asc';
  903. } else {
  904. // 非当前选项,点击时,以图标所示的顺序排序
  905. currentStatus.order = button.textContent === '⇧' ? 'asc' : 'desc';
  906. // 修改非当前选项按钮的图标
  907. for (const key in allButtons) {
  908. if (key === by) continue;
  909. if (Object.hasOwnProperty.call(allButtons, key)) {
  910. const btnItem = allButtons[key];
  911. if (btnItem.el.textContent === '⬆') {
  912. btnItem.el.textContent = '⇧';
  913. } else if (btnItem.el.textContent === '⬇') {
  914. btnItem.el.textContent = '⇩';
  915. }
  916. }
  917. }
  918. }
  919. button.textContent = currentStatus.order === 'asc' ? '⬆' : '⬇';
  920. currentStatus.by = by;
  921. sortFileList();
  922. sortFolderList();
  923.  
  924. }
  925.  
  926. // create buttons
  927. setTimeout(() => {
  928. if (allButtons === undefined && menu_value('menu_fileSort')) {
  929. allButtons = createAllButtons();
  930. // console.log(allButtons);
  931. allButtons[currentStatus.by].el.textContent = currentStatus.order === 'asc' ? '⬆' : '⬇';
  932. }
  933. }, 500);
  934.  
  935. // sort files
  936. const fileList = frameDoc.querySelector('#filelist');
  937. const fileObserver = new MutationObserver(fileListCallback);
  938. fileObserver.observe(fileList, { childList: true, attributes: false });
  939.  
  940. // sort folders
  941. const folderList = frameDoc.querySelector('#sub_folder_list');;
  942. const folderObserver = new MutationObserver(folderListCallback);
  943. folderObserver.observe(folderList, { childList: true, attributes: false });
  944.  
  945.  
  946. }
  947. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址