番茄小说阅读辅助器

可以下载番茄小说内容,记录阅读位置(滚动位置),可以自动滚动,快捷书签,好用!

تثبيت هذا البرنامج النصي؟
سكربت موصى به للمؤلف

ربما يعجبك أيضا dialog-gui.

تثبيت هذا البرنامج النصي
  1. // ==UserScript==
  2. // @name 番茄小说阅读辅助器
  3. // @namespace http://tampermonkey.net/
  4. // @version 2.16
  5. // @description 可以下载番茄小说内容,记录阅读位置(滚动位置),可以自动滚动,快捷书签,好用!
  6. // @author twjx
  7. // @match *://fanqienovel.com/*
  8. // @require https://cdn.jsdelivr.net/npm/lil-gui@0.16
  9. // @require https://update.greasyfork.org/scripts/522780/1518758/dialog-gui.js
  10. // @require https://update.greasyfork.org/scripts/521360/1514728/unicode1.js
  11. // @license GNU AGPLv3
  12. // @resource swalStyle https://unpkg.com/sweetalert2@10.16.6/dist/sweetalert2.min.css
  13. // @icon data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTE4Ljg3MjcgMEg1LjEyNzI3QzIuMjkwOTEgMCAwIDIuMjkwOTEgMCA1LjEyNzI3VjE4Ljg3MjdDMCAyMS43MDkxIDIuMjkwOTEgMjQgNS4xMjcyNyAyNEgxOC44NzI3QzIxLjcwOTEgMjQgMjQgMjEuNzA5MSAyNCAxOC44NzI3VjUuMTI3MjdDMjQgMi4yOTA5MSAyMS43MDkxIDAgMTguODcyNyAwWiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik01LjEyNzI3IDBIMTguODcyN0MyMS43MDkxIDAgMjQgMi4yOTA5MSAyNCA1LjEyNzI3VjE4Ljg3MjdDMjQgMjEuNzA5MSAyMS43MDkxIDI0IDE4Ljg3MjcgMjRINS4xMjcyN0MyLjI5MDkxIDI0IDAgMjEuNzA5MSAwIDE4Ljg3MjdWNS4xMjcyN0MwIDIuMjkwOTEgMi4yOTA5MSAwIDUuMTI3MjcgMFpNMjMuNDc1NyA1LjEyNzI3QzIzLjQ3NTcgMi41OTYzNiAyMS40MDMgMC41MjM2MzYgMTguODcyIDAuNTIzNjM2SDUuMTI2NTlDMi41OTU2OCAwLjUyMzYzNiAwLjUyMjk0OSAyLjU5NjM2IDAuNTIyOTQ5IDUuMTI3MjdWMTguODcyN0MwLjUyMjk0OSAyMS40MDM2IDIuNTk1NjggMjMuNDc2NCA1LjEyNjU5IDIzLjQ3NjRIMTguODcyQzIxLjQwMyAyMy40NzY0IDIzLjQ3NTcgMjEuNDAzNiAyMy40NzU3IDE4Ljg3MjdWNS4xMjcyN1oiIGZpbGw9IiNFNkU2RTYiLz4KPHBhdGggZD0iTTE1LjA3NjIgMFY1LjA0TDE3LjAxOCAzLjkyNzI3TDE4Ljk1OTggNS4wNFYwSDE1LjA3NjJaIiBmaWxsPSIjRUU1NTI4Ii8+CjxwYXRoIGQ9Ik0yNCAxMy45NjM2QzIxLjI1MDkgMTAuNjkwOCAxNi45MDkxIDguNTc0NDYgMTIuMDIxOCA4LjU3NDQ2QzcuMDkwOTEgOC41NzQ0NiAyLjcyNzI3IDEwLjcxMjYgMCAxNC4wMjlWMTguODcyNkMwIDIxLjcwOSAyLjI5MDkxIDIzLjk5OTkgNS4xMjcyNyAyMy45OTk5SDE4Ljg3MjdDMjEuNzA5MSAyMy45OTk5IDI0IDIxLjcwOSAyNCAxOC44NzI2VjEzLjk2MzZaIiBmaWxsPSJ1cmwoI3BhaW50MF9yYWRpYWxfNjA3XzEyNTA1KSIvPgo8cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTEyLjc4NTYgMTMuODk4MkMxMi43NjM4IDEzLjAwMzcgMTIuNDE0NyAxMi41ODkxIDEyLjAwMDIgMTIuNTg5MUMxMS41NjM4IDEyLjYxMDkgMTEuMjM2NSAxMy4wMjU1IDExLjI1ODQgMTMuODk4MkMxMS4yNTg0IDE0LjgxNDYgMTIuMDQzOCAxNS44NjE4IDEyLjA0MzggMTUuODYxOEMxMi4wNDM4IDE1Ljg2MTggMTIuNzg1NiAxNC44MTQ2IDEyLjc4NTYgMTMuODk4MlpNNi4zNDk0NiAxOC42NzYzQzcuMjY1ODMgMTguNjc2MyA4LjMxMzEgMTkuNDE4MSA4LjMxMzEgMTkuNDE4MUM4LjMxMzEgMTkuNDE4MSA3LjI2NTgzIDIwLjIwMzUgNi4zNDk0NiAyMC4yMDM1QzUuNDMzMSAyMC4yMDM1IDUuMDE4NTUgMTkuODc2MyA1LjAxODU1IDE5LjQzOTlDNS4wNDAzNyAxOS4wNDcyIDUuNDU0OTIgMTguNjk4MSA2LjM0OTQ2IDE4LjY3NjNaTTE4Ljk2MSAxOS40NjE5QzE4Ljk2MSAxOS44NzY0IDE4LjU0NjUgMjAuMjI1NSAxNy42MzAxIDIwLjIyNTVDMTYuNzEzOCAyMC4yMjU1IDE1LjY2NjUgMTkuNDQwMSAxNS42NjY1IDE5LjQ0MDFDMTUuNjY2NSAxOS40NDAxIDE2LjczNTYgMTguNjc2NCAxNy42MzAxIDE4LjY5ODJDMTguNTQ2NSAxOC42OTgyIDE4Ljk2MSAxOS4wMjU1IDE4Ljk2MSAxOS40NjE5Wk0xNy4zMDIyIDE0Ljg1ODFDMTcuNjA3NiAxNS4xNjM1IDE3LjU0MjIgMTUuNjg3MiAxNi44ODc2IDE2LjM0MTdDMTYuMjMzMSAxNi45NzQ1IDE0Ljk0NTggMTcuMTcwOCAxNC45NDU4IDE3LjE3MDhDMTQuOTQ1OCAxNy4xNzA4IDE1LjE2NCAxNS44ODM1IDE1LjgxODUgMTUuMjUwOEMxNi40NzMxIDE0LjU5NjMgMTcuMDE4NSAxNC41NTI2IDE3LjMwMjIgMTQuODU4MVpNOS4wNTU2NCAxNy4xNDkyQzkuMDU1NjQgMTcuMTQ5MiA4LjgzNzQ2IDE1Ljg2MiA4LjE4MjkxIDE1LjIyOTJDNy41MjgzNiAxNC41OTY1IDYuOTgyOTEgMTQuNTUyOSA2LjY5OTI3IDE0LjgzNjVDNi40MTU2NCAxNS4xNDIgNi40NTkyNyAxNS42ODc0IDcuMTEzODIgMTYuMzIwMUM3Ljc2ODM2IDE2Ljk1MjkgOS4wNTU2NCAxNy4xNDkyIDkuMDU1NjQgMTcuMTQ5MloiIGZpbGw9IndoaXRlIi8+CjxkZWZzPgo8cmFkaWFsR3JhZGllbnQgaWQ9InBhaW50MF9yYWRpYWxfNjA3XzEyNTA1IiBjeD0iMCIgY3k9IjAiIHI9IjEiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiBncmFkaWVudFRyYW5zZm9ybT0idHJhbnNsYXRlKDEyLjA5ODkgMjQuMjEyKSBzY2FsZSgxNC41OTg0IDkuMzgyNzcpIj4KPHN0b3Agc3RvcC1jb2xvcj0iI0NDMDUwMCIvPgo8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiNGRjVGMDAiLz4KPC9yYWRpYWxHcmFkaWVudD4KPC9kZWZzPgo8L3N2Zz4K
  14. // @grant none
  15. // ==/UserScript==
  16.  
  17. (function() {
  18. 'use strict';
  19. window.data=''
  20. window.num=0
  21. window.alldata=[]
  22. window.onstop=false
  23. window.movep=[]
  24. window.img=[]
  25. window.thedata
  26. window.unicode_data()
  27. window.sleep=async function(ms){
  28. return new Promise(resolve => setTimeout(resolve, ms));
  29. }
  30. window.downloader={
  31. xml:function(type, src,idata,num,num1,aa) {
  32. const xhr = new XMLHttpRequest();
  33. xhr.open(type, src);
  34. xhr.overrideMimeType('text/plain; charset=utf-8');
  35. xhr.onload = function () {
  36. if (xhr.status === 200) {
  37. const responseText = xhr.responseText;
  38. let content = responseText.split('content noselect"><div>')[1]
  39. .split('</div><p></p>')[0]
  40. .replaceAll('<p>', '')
  41. .replaceAll('</p>', '\n');
  42. var decoded = downloader.decode(content);
  43. var text=downloader.find_img(decoded)
  44. if(text!==false){
  45. var f=decoded.split('<div data-fanqie-type="image" ')
  46. var textd=''
  47. for(let x of f){
  48. if(x.startsWith('source')){
  49. textd+='\n此处有一张图片已去除,请于下载配套中查看\n名称:'+x.split('1">')[2].split('\n')[0]+'\n'+x.split('</div>')[1]
  50. }else textd+=x
  51. }
  52. for(let x=0;x<text.length;x++){
  53. img.push({
  54. chapter:responseText.split('<title>')[1].split('在线免费阅读_番茄小说官网<')[0].split(' ')[0].split('第')[1].replace('章',''),
  55. chapter1:num1,
  56. chapter2:num,
  57. name:responseText.split('<title>')[1].split('在线免费阅读_番茄小说官网<')[0].split(' ')[1],
  58. src:text[x][1],
  59. title:text[x][0],
  60. })
  61. }
  62. decoded=textd
  63. }
  64. idata.data.push({
  65. chapter:responseText.split('<title>')[1].split('在线免费阅读_番茄小说官网<')[0].split(' ')[0].split('第')[1].replace('章',''),
  66. chapter1:num1,
  67. chapter2:num,
  68. name:responseText.split('<title>')[1].split('在线免费阅读_番茄小说官网<')[0].split(' ')[1],
  69. data:decoded,
  70. })
  71. if(decoded==undefined){onstop=true;window.d={a:responseText,b:decoded,c:text,d:textd}}
  72. console.log(aa+' 机改1:'+num1+' 机改2:'+num+'下载完成')
  73. }
  74. };
  75. xhr.send();
  76. },
  77. decode:function(content) {
  78. var newdata = '';
  79. for (let x of content) {
  80. if (String(x).charCodeAt(0) in unicode_data == true) {
  81. newdata += unicode_data[String(x).charCodeAt(0)];
  82. } else {
  83. newdata += String(x);
  84. }
  85. }
  86. return newdata;
  87. },
  88. dispose:async function(children,type){
  89. if(onstop==true)return;
  90. var jdata=children.children[0].innerHTML.split('<span class="volume-dot"></span>')
  91. var num=1
  92. alldata.push({
  93. name:jdata[0],
  94. volume:jdata[0],
  95. allchapter:jdata[1],
  96. data:[]})
  97. console.log('卷创建完毕')
  98. for(let x of children.children[1].children){
  99. if(onstop==true)return;
  100. this.xml('GET',x.children[0].href,alldata[alldata.length-1],num,num1,x.innerText.split(' ')[0])
  101. num+=1
  102. num1+=1
  103. await sleep(Number(document.querySelectorAll('.widget')[2].children[0].value))//50毫秒一下最好不要,卡爆
  104. }
  105. },
  106. find_img:function(text){
  107. if(text.includes('<div data-fanqie-type="image" ')){
  108. var returntext=[]
  109. var texta=text.split('<div data-fanqie-type="image" ')
  110. for(let x of texta){
  111. if(x.startsWith('source="')){
  112. var textb=x.split('Desc" group')
  113. returntext[texta.indexOf(x)-1]=[textb[1].split('\n')[0].split('>')[1],textb[0].split('<img src="')[1].split('" width="')[0]]
  114. }
  115. }
  116. return returntext
  117. }else return false
  118. },
  119. download:function(name, text,type) {
  120. var dld = document.createElement('a');
  121. dld.setAttribute('href', 'data:text/plain;charset=utf-8,'+encodeURIComponent(text));
  122.  
  123. dld.setAttribute('download', name);
  124. dld.click();
  125. },
  126. downloadd:async function(type){
  127. data=''
  128. console.log('正在排序...')
  129. window.d=0
  130. for(let x=0;x<alldata.length;x++){
  131. data+=alldata[x].name+' '+alldata[x].allchapter+'\n'
  132. for(let x1=0;x1<alldata[x].data.length;x1++){
  133. d+=1
  134. for(let x2 of alldata[x].data){
  135. if(x2.chapter1==d){
  136. data+='第'+[x2.chapter,x2.chapter1,x2.chapter2][type]+'章 '+x2.name+'\n'+x2.data
  137. }
  138. }
  139. }
  140. }
  141. this.download(window.__INITIAL_STATE__.page.bookName,window.__INITIAL_STATE__.page.bookName+"\n此文件由番茄小说阅读辅助器下载https://greasyfork.org/zh-CN/scripts/521377-番茄小说阅读辅助器\n请支持正版番茄小说\n作者:"+window.__INITIAL_STATE__.page.author+'\n'+data,'text')
  142. alert('下载完成')
  143. /*var imgtext=''
  144. for(let x of img){
  145. imgtext+='图片名称'+x.title+' 来自章节 第'+[x.chapter,x.chapter1,x.chapter2][type]+'章 '+x.name+'\n'
  146. this.download(x.title,x.src,'img')
  147. }*/
  148. await sleep(100)
  149. //this.download(window.__INITIAL_STATE__.page.bookName,window.__INITIAL_STATE__.page.bookName+' 图片来源',imgtext,'text')
  150. gui.domElement.children[1].children[0].children[1].children[2].remove()
  151. await sleep(1000)
  152. data=''
  153. alldata=[]
  154. },
  155. loadrecord:function(){
  156. document.querySelectorAll('.chapter-item').forEach((x)=>{
  157. var recorddata=thedata.read.read_record.filter(e=>e.chapterid==x.children[0].href.split('/')[4])
  158. if(recorddata.length==1){
  159. x.innerHTML+='<span class="tooltip">已看'+Math.round(((recorddata[0].scrolltop+window.innerHeight)/recorddata[0].scrollHeight)*100)+'%</span>'
  160. }else{
  161. x.innerHTML+='<span class="tooltip">未看</span>'
  162. }
  163. })
  164. console.log('tips is loaded')
  165. },
  166. addstyle:function(){
  167. document.querySelector('.page').innerHTML+=`<style>
  168. .tooltip {
  169. visibility: hidden; /* 初始状态下隐藏工具提示 */
  170. background-color: #555;
  171. color: #fff;
  172. text-align: center;
  173. border-radius: 5px;
  174. padding: 5px 10px;
  175. position: absolute; /* 使用绝对定位 */
  176. z-index: 1; /* 确保工具提示显示在其他元素之上 */
  177. bottom: 125%; /* 工具提示显示在按钮上方 */
  178. left: 25%;
  179. transform: translateX(-50%);
  180. opacity: 0; /* 初始状态下透明度为0 */
  181. transition: opacity 0.3s; /* 添加过渡效果 */
  182. }
  183. .chapter-item:hover .tooltip {
  184. visibility: visible; /* 鼠标悬停时显示工具提示 */
  185. opacity: 1; /* 鼠标悬停时设置透明度为1 */
  186. }
  187. </style>`
  188.  
  189. },
  190. }
  191. function move(){//移动模块
  192. var guid=gui.domElement
  193. gui.domElement.children[0].onmousedown=function(e) {
  194. if(guid.style.left==''){
  195. movep=[e.clientX-(window.innerWidth-275),e.clientY-0]//首次移动
  196. }else{
  197. movep=[e.clientX-Number(guid.style.left.replace('px','')),e.clientY-Number(guid.style.top.replace('px',''))]
  198. }
  199. window.onmove=true
  200. }
  201. document.onmouseup=function(e) {
  202. movep=[]
  203. window.onmove=false
  204. if(Number(guid.style.left.replace('px',''))<0)guid.style.left='0px';
  205. if(Number(guid.style.top.replace('px',''))<0)guid.style.top='0px';
  206. if(Number(gui.domElement.style.left.replace('px',''))+260>=windowWidth){
  207. gui.domElement.style.left=(windowWidth-260)+'px'
  208. }
  209. }
  210. document.onmousemove=function(e){
  211. if(window.onmove==true){
  212. guid.style.top=e.clientY-movep[1]+'px';
  213. guid.style.left=e.clientX-movep[0]+'px'
  214. }
  215. }
  216. guid.onmouseover=function(){
  217. if(!guid.children[0].innerText.includes('右'))guid.children[0].innerText+=' (右键可移动)';
  218. }
  219. guid.onmouseout=function(){
  220. guid.children[0].innerText='番茄阅读辅助器'
  221. }
  222. }
  223. window.reader={
  224. record:async function(){//记录阅读位置
  225. window.time=String(new Date).split(' ')
  226. var datax=thedata.read.read_record.filter(e=>e.chapterid==location.pathname.split('/')[2])
  227. if(datax.length==1){
  228. //回忆了以前的知识
  229. if(thescroll.scrollTop==0){await sleep(500)}
  230. Object.assign(thedata.read.read_record.filter(e=>e.chapterid==location.pathname.split('/')[2])[0],{
  231. date:{
  232. year:time[3],
  233. month:time[2],
  234. time:time[4],
  235. area:time[6],
  236. },
  237. chapterName:document.querySelector('.muye-reader-title').innerText,
  238. chapterid:location.pathname.split('/')[2],
  239. scrolltop:thescroll.scrollTop,
  240. scrollHeight:thescroll.scrollHeight,
  241. })
  242. }else if(datax.length==0){
  243. thedata.read.read_record.push({
  244. date:{
  245. year:time[3],
  246. month:time[2],
  247. time:time[4],
  248. area:time[6],
  249. },
  250. bookName:document.querySelector('.muye-reader-nav-title').innerText,
  251. chapterName:document.querySelector('.muye-reader-title').innerText,
  252. chapterid:location.pathname.split('/')[2],
  253. scrolltop:thescroll.scrollTop,
  254. scrollHeight:thescroll.scrollHeight,
  255. })
  256. }
  257. },
  258. onload:function(){//加载阅读位置
  259. if(thedata.read.read_record.filter(e=>e.chapterid==location.pathname.split('/')[2]).length==1){
  260. thescroll.scrollTop=thedata.read.read_record.filter(e=>e.chapterid==location.pathname.split('/')[2])[0].scrolltop
  261. console.log('记录加载')
  262. }
  263. },
  264. loadrecord:function(){//加载目录记录
  265. for(let x of document.querySelector('.reader-catalog-chapters').children){
  266. for(let xx of x.children){
  267. if(xx.className!=='volume-header'){
  268. var xxx=thedata.read.read_record.filter(e=>e.chapterid==xx.children[0].attributes[0].value)
  269. if(xxx.length==1){
  270. xx.children[0].innerHTML+='<p> 已看'+Math.round(((xxx[0].scrolltop+thescroll.clientHeight)/xxx[0].scrollHeight)*100)+'%</p>'
  271. }}
  272. }
  273. }
  274. console.log('目录记录加载')
  275. },
  276. scroll:{
  277. load:function(theparent){
  278. this.scrollInterval;
  279. this.scrollStatus = theparent.add({ status: '已停止' }, 'status').name('滚动状态');
  280. this.scrollStatus.domElement.style.color = 'red';
  281. this.scrollSpeed = theparent.add({ speed: 1 }, 'speed').name('滚动速度');
  282. this.scrollSpeed.setValue(thedata.read.scroll_speed)
  283. this.scrollSpeedsave = theparent.add({ speedsave: false }, 'speedsave').name('保存速度').onChange(function(value) {
  284. if (value==true) {
  285. thedata.read.scroll_speed=reader.scroll.scrollSpeed.getValue()
  286. console.log('保存速度:'+thedata.read.scroll_speed)
  287. fqxsydqdata.savedata()
  288. }
  289. });
  290. this.stopButton = theparent.add(this, 'start').name('开始自动滚动');
  291. },
  292. autoScroll:function() {
  293. if (thescroll.scrollTop >= thescroll.scrollHeight - thescroll.clientHeight) {
  294. console.log('滚动以至底部')
  295. window.reader.scroll.stopAutoScroll();
  296. }else{
  297. thescroll.scrollTop += Math.round(reader.scroll.scrollSpeed.getValue())
  298. }
  299. },
  300. startAutoScroll:function() {
  301. this.scrollInterval = setInterval(this.autoScroll, 200);
  302. this.scrollStatus.setValue('进行中');
  303. this.stopButton.name('停止自动滚动');
  304. this.scrollStatus.domElement.style.color = 'green';
  305. },
  306. stopAutoScroll:function() {
  307. clearInterval(this.scrollInterval);
  308. this.scrollStatus.setValue('已停止');
  309. this.stopButton.name('开始自动滚动');
  310. this.scrollStatus.domElement.style.color = 'red';
  311. },
  312. "start":()=>{
  313. var x=reader.scroll
  314. if(x.scrollStatus.getValue()=='已停止'){
  315. if(String(Number(x.scrollSpeed.getValue()))=='NaN'){
  316. alert('滚动速度输入非数字')
  317. return
  318. }
  319. if(x.scrollSpeed.getValue()>=1000){
  320. alert('滚动速度输入过大\n如有需要请在脚本后台修改上限\n如有错误作者概不负责')
  321. return
  322. }
  323. console.log('滚动速度:'+Math.round(x.scrollSpeed.getValue()))
  324. x.startAutoScroll();
  325. }else{
  326. x.stopAutoScroll();
  327. }
  328. }
  329. },
  330. keyboard:function(value){
  331. value.addEventListener("keydown", async function (e) {
  332. if(reader.mark.onchoose==true){
  333. await sleep(200)
  334. page1_2_2.children[1].domElement.children[1].children[0].value=e.key+'键'
  335. }
  336. });
  337. document.addEventListener("keyup", function (e) {
  338. delete reader.mark.keydown[e.key]
  339. if(reader.mark.onaddmark[2]==e.key){
  340. message('停止添加')
  341. reader.mark.onaddmark=[0,false,''];
  342. }
  343. })
  344. document.addEventListener("keydown", function (e) {
  345. if(reader.mark.ontransmission[0]==true && e.key!==reader.mark.ontransmission[1]){
  346. message('停止传送','',true)
  347. reader.mark.ontransmission=[false,'']
  348. }
  349. reader.mark.keydown[e.key]=true
  350. if('d' in reader.mark.keydown && Object.keys(reader.mark.keydown).filter(e=>String(Number(e))!=='NaN').length==1 && reader.mark.ondelmark[1]==false){
  351. message('请你持续按住'+e.key+'键 3秒 删除书签'+Object.keys(reader.mark.keydown).filter(e=>String(Number(e))!=='NaN')[0],'1')
  352. if(reader.mark.onaddmark[1]==true){
  353. message('你已经在进行删除书签的操作,为防止出错已暂停所有进程','1',true)
  354. reader.mark.onaddmark=[0,false,''];
  355. return
  356. }
  357. reader.mark.ondelmark=[0,true,Object.keys(reader.mark.keydown).filter(e=>String(Number(e))!=='NaN')[0]]
  358. var timer1=setInterval(()=>{
  359. if(reader.mark.ondelmark[1]==false){
  360. clearInterval(timer)
  361. }
  362. reader.mark.ondelmark[0]+=0.1
  363. if(reader.mark.ondelmark[0]>=3){
  364. clearInterval(timer1)
  365. Object.assign(thedata.read.bookmark['data'+reader.mark.ondelmark[2]],{
  366. bookName:'',
  367. bookid:'',
  368. chapterName:'',
  369. chapterid:'',
  370. scrolltop:0,
  371. time:{
  372. date:'',
  373. },
  374. })
  375. fqxsydqdata.savedata()
  376. message('书签'+reader.mark.ondelmark[2]+'删除成功','1',true)
  377. setTimeout(()=>{reader.mark.ondelmark=[0,false,'']},2000)
  378. }
  379. },100)
  380. }else if(String(Number(e.key))!=='NaN' && Object.values(thedata.read.bookmark['data'+e.key]).filter(e=>e=='').length==5 && reader.mark.onaddmark[2]!==e.key && reader.mark.ondelmark[1]==false){
  381. if(reader.mark.onaddmark[1]==true){
  382. message('你已经在进行添加书签的操作,为防止出错已暂停所有进程','1',true)
  383. reader.mark.onaddmark=[0,false,''];
  384. return
  385. }
  386. message('请你持续按住'+e.key+'键 3秒 添加书签'+e.key,'1')
  387. reader.mark.onaddmark=[0,true,e.key]
  388. var timer=setInterval(()=>{
  389. if(reader.mark.onaddmark[1]==false){
  390. clearInterval(timer)
  391. }
  392. reader.mark.onaddmark[0]+=0.1
  393. if(reader.mark.onaddmark[0]>=3){
  394. clearInterval(timer)
  395. thedata.read.bookmark['data'+reader.mark.onaddmark[2]]={
  396. bookName:window.__INITIAL_STATE__.reader.chapterData.bookName,
  397. bookid:window.__INITIAL_STATE__.reader.chapterData.bookId,
  398. chapterName:window.__INITIAL_STATE__.reader.chapterData.title,
  399. chapterid:location.pathname.split('/')[2],
  400. scrolltop:thescroll.scrollTop,
  401. time:{
  402. date:String(new Date),
  403. },
  404. }
  405. fqxsydqdata.savedata()
  406. message('书签'+reader.mark.onaddmark[2]+'添加成功','1',true)
  407. setTimeout(()=>{reader.mark.onaddmark=[0,false,'']},2000)
  408. }
  409. },100)
  410. }else if(String(Number(e.key))!=='NaN' && Object.values(thedata.read.bookmark['data'+e.key]).filter(e=>e==='').length==0 && Object.values(reader.mark.keydown).length==1 && reader.mark.onaddmark[1]==false && reader.mark.ondelmark[1]==false){
  411. message('开始传送至书签'+e.key+' 3秒内按其他键取消传送')
  412. reader.mark.ontransmission=[true,e.key]
  413. setTimeout(()=>{
  414. if(reader.mark.ontransmission[0]==true){
  415. reader.record()
  416. window.location.pathname='/reader/'+thedata.read.bookmark['data'+reader.mark.ontransmission[1]].chapterid
  417. }
  418. },3000)
  419. }
  420. });
  421. },
  422. mark:{
  423. onaddmark:[0,false,''],
  424. ondelmark:[0,false,''],
  425. onchoose:false,
  426. ontransmission:[false,''],
  427. keydown:{},
  428. },
  429. bookmark:function(theparent){
  430. var page1_2_1 = theparent.addFolder('书签').close()
  431. page1_2_1.add({ del:()=>{
  432. message('已清除本书所有书签','',true)
  433. fqxsydqdata.update('bookmark')
  434. fqxsydqdata.savedata()
  435. }}, 'del').name('删除书签')
  436. window. page1_2_2 = theparent.addFolder('快捷键').close()
  437. page1_2_2.add({ addbookmark: '数字键1-9(暂不支持更改)' }, 'addbookmark').name('增加书签').onFinishChange((value)=>{
  438. page1_2_2.children[0].$input.value='数字键1-9(暂不支持更改)'
  439. })
  440. page1_2_2.add({ delbookmark: '键'+thedata.read.shortcut_key.changemark+'+对应的数字键1-9' }, 'delbookmark').name('删除书签');
  441. var input=page1_2_2.children[1].$input
  442. this.keyboard(input)
  443. input.onfocus=function(x){
  444. input.value=''
  445. reader.mark.onchoose=true;
  446. }
  447. input.onblur=function(x){
  448. if(input.value!==''){
  449. thedata.read.shortcut_key.changemark=input.value.replace('键','')
  450. fqxsydqdata.savedata()
  451. }
  452. reader.mark.onchoose=false;
  453. }
  454. },
  455. }
  456. window.fqxsydqdata={
  457. getdata:function(){
  458. if(!localStorage.fqxsydq){
  459. window.thedata={
  460. name:'番茄阅读辅助器',
  461. version:'1.540',
  462. read:{
  463. read_record:[],
  464. last_read:{},
  465. scroll_speed:1,
  466. shortcut_key:{
  467. changemark:'d',
  468. },
  469. bookmark:{
  470.  
  471. },
  472. },
  473. download:{
  474. },
  475. }
  476. this.update('bookmark')
  477. localStorage.fqxsydq=JSON.stringify(thedata)
  478. }else{
  479. window.thedata=JSON.parse(localStorage.fqxsydq)
  480. if(!thedata.read.bookmark){
  481. window.thedata={
  482. name:'番茄阅读辅助器',
  483. version:'2.00',
  484. read:{
  485. read_record:thedata.read.read_record,
  486. last_read:{},
  487. scroll_speed:thedata.read.scroll_speed,
  488. shortcut_key:{
  489. changemark:'d',
  490. },
  491. bookmark:{
  492.  
  493. },
  494. },
  495. download:{
  496. },
  497. }
  498. this.update('bookmark')
  499. alert('原版本数据格式低,已更新,原数据未删改')
  500. }
  501. }
  502. },
  503. savedata:function(){
  504. localStorage.fqxsydq=JSON.stringify(thedata)
  505. },
  506. update:function(type){
  507. if(type=='bookmark'){//更新书签格式 1.531及版本之前的格式
  508. console.log('bookmark已更新/重置')
  509. thedata.read.bookmark={
  510. data1:{
  511. bookName:'',
  512. bookid:'',
  513. chapterName:'',
  514. chapterid:'',
  515. scrolltop:0,
  516. time:{
  517. date:'',
  518. },
  519. },
  520. data2:{},data3:{},data4:{},data5:{},data6:{},data7:{},data8:{},data9:{},
  521. }
  522. var bookmark1=new Map()//建obj
  523. for(let x=2;x<10;x++){
  524. bookmark1.set('data'+x,thedata.read.bookmark.data1)
  525. }
  526. Object.assign(thedata.read.bookmark,Object.fromEntries(bookmark1))
  527. }
  528. }
  529. }
  530. window.q=function(){
  531. alert('原版:下载原版章节\n机翻1:下载机翻1章节\n机翻2:下载机翻2章节\n机翻1效果如下\n第一卷\n第1章\n第2章\n......\n第二卷\n第100章...\n机翻2\n第一卷\n第1章\n第2章\n......\n第二卷\n第1章')
  532. }
  533. window.message=function(text,str,onclose,parent){
  534. if(document.querySelector('.dialog'))document.querySelector('.dialog').remove();
  535. var ele= dialog.create({
  536. type: "single",
  537. title: "",
  538. dark_screen: false,
  539. enMove: false,
  540. attribute: {
  541. position:'relative',
  542. height:'0px',
  543. top:'',
  544. },
  545. content: [
  546. {
  547. type: "text",
  548. returnElement: str,
  549. content: {
  550. type: 'h2',
  551. content: text,
  552. },
  553. style:{
  554.  
  555. },
  556. },
  557. ]
  558. },document.querySelector('.muye-reader') ? document.querySelector('.muye-reader'):document.querySelector('.page'));
  559. if(location.href.includes('/reader/')){
  560. dialog.dialog.style.top=(-thescroll.clientWidth/2+thescroll.scrollTop)+'px'
  561. }else{
  562. dialog.dialog.style.top=(-(document.querySelector('.page').scrollHeight-document.querySelector('.page').scrollTop)+innerHeight/2+30)+'px'
  563. }
  564. if(onclose==true){
  565. setTimeout(()=>{document.querySelector('.dialog').remove()},3000)
  566. }
  567. return ele
  568. }
  569. window.main = {
  570. "copybook" : async()=>{
  571. data=''
  572. img=[]
  573. if(Number(document.querySelectorAll('.widget')[2].children[0].value)<60){
  574. var b=confirm('小于60毫秒作者建议请一下后台\n开的时候玩手机就行了\n作者亲测50毫秒间隔下载也不会出错')
  575. if(!b==true)return;
  576. }
  577. console.log('下载模式:'+document.querySelectorAll('.widget')[1].children[0].value)
  578. var type=['原版','机改1','机改2'].indexOf(document.querySelectorAll('.widget')[1].children[0].value)
  579. page1.add(main,'stop').name('暂停下载')
  580. document.querySelectorAll('.tooltip').forEach(x=>x.remove())
  581. message('请等待提示,现开始复制\n可通过控制台查看进度\n会暂时去除显示进度功能','',true)
  582. globalThis.a=document.querySelector('.page-directory-content')
  583. globalThis.num1=1
  584. for(let x of a.children){
  585. if(onstop==true)return;
  586. await downloader.dispose(x,'computer')
  587. await sleep(150)
  588. }
  589. await downloader.downloadd(type)
  590. downloader.loadrecord()
  591. },
  592. "stop":async()=>{
  593. onstop=true
  594. alert('已暂停')
  595. gui.domElement.children[1].children[0].children[1].children[2].innerText='已暂停'
  596. await sleep(5000)
  597. gui.domElement.children[1].children[0].children[1].children[2].remove()
  598. },
  599. };
  600. window.gui = new lil.GUI({ title: '番茄阅读辅助器' });
  601. window.gui.domElement.style.userSelect = 'none';
  602. move()
  603. fqxsydqdata.getdata()
  604. if(location.href.includes('force_mobile=1')){
  605. alert('暂不支持手机排版的下载\n如使用电脑请保证长宽比例不低于1\n防止排版进入手机格式')
  606. return
  607. }
  608. var page1
  609. if(location.href.includes('/page/')){
  610. page1 = gui.addFolder('复制')
  611. page1.add(main,'copybook').name('复制本书全文 (仅支持电脑)')
  612. page1.add({setting:1},'setting',{'原版':1,'机改1':2,'机改2':3}).name('下载设置')
  613. page1.add({a:100},"a").min(1).name('下载速度')
  614. document.querySelectorAll('.controller')[1].innerHTML+='<div class="question">?</div>'
  615. document.querySelector('.question').addEventListener('click',()=>{window.q()})
  616. downloader.loadrecord()
  617. downloader.addstyle()
  618. }
  619. else if(location.href.includes('/reader/')){
  620. window.thescroll=document.querySelector('.muye-reader')
  621. reader.onload()
  622. window.scrollhref=location.pathname
  623. thescroll.onscroll=function(e){
  624. if(scrollhref!==location.pathname){
  625. reader.onload()
  626. window.scrollhref=location.pathname
  627. return
  628. }
  629. reader.record()
  630. fqxsydqdata.savedata()
  631. }
  632. document.querySelectorAll('.reader-toolbar-item')[1].addEventListener('click',async()=>{
  633. await sleep(1500)
  634. reader.loadrecord()
  635. })
  636. page1 = gui.addFolder('阅读')
  637. var page1_1 = page1.addFolder('滚动').close()
  638. var page1_2 = page1.addFolder('书签').close()
  639. reader.scroll.load(page1_1)
  640. reader.bookmark(page1_2)
  641. }
  642. })();