My Novel Reader

小说阅读脚本,统一阅读样式,内容去广告、修正拼音字、段落整理,自动下一页

ของเมื่อวันที่ 20-12-2017 ดู เวอร์ชันล่าสุด

  1. /* This script build by rollup. */
  2. (function (Vue) {
  3. 'use strict';
  4.  
  5. function __$styleInject( css ) {
  6. if(!css) return ;
  7.  
  8. if(typeof(window) == 'undefined') return ;
  9. let style = document.createElement('style');
  10. style.setAttribute('media', 'screen');
  11. style.setAttribute('class', 'noRemove');
  12.  
  13. style.innerHTML = css;
  14. document.head.appendChild(style);
  15. return css;
  16. }
  17.  
  18. Vue = Vue && Vue.hasOwnProperty('default') ? Vue['default'] : Vue;
  19.  
  20. // ==UserScript==
  21. // @id mynovelreader@ywzhaiqi@gmail.com
  22. // @name My Novel Reader
  23. // @name:zh-CN 小说阅读脚本
  24. // @name:zh-TW 小說閱讀腳本
  25. // @version 6.2.2
  26. // @namespace https://github.com/ywzhaiqi
  27. // @author ywzhaiqi
  28. // @contributor Roger Au, shyangs, JixunMoe、akiba9527 及其他网友
  29. // @description 小说阅读脚本,统一阅读样式,内容去广告、修正拼音字、段落整理,自动下一页
  30. // @description:zh-CN 小说阅读脚本,统一阅读样式,内容去广告、修正拼音字、段落整理,自动下一页
  31. // @description:zh-TW 小說閱讀腳本,統一閱讀樣式,內容去廣告、修正拼音字、段落整理,自動下一頁
  32. // @license GPL version 3
  33. // @grant GM_xmlhttpRequest
  34. // @grant GM_addStyle
  35. // @grant GM_getValue
  36. // @grant GM_setValue
  37. // @grant GM_getResourceURL
  38. // @grant GM_openInTab
  39. // @grant GM_setClipboard
  40. // @grant GM_registerMenuCommand
  41. // @grant GM_info
  42. // @grant unsafeWindow
  43. // @homepageURL https://greasyfork.org/scripts/292/
  44. // @require https://cdn.staticfile.org/vue/2.2.6/vue.min.js
  45. // @require https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js
  46. // @require https://cdn.staticfile.org/underscore.js/1.7.0/underscore-min.js
  47. // @require https://cdn.staticfile.org/keymaster/1.6.1/keymaster.min.js
  48. // @require https://greasyfork.org/scripts/2672-meihua-cn2tw/code/Meihua_cn2tw.js?version=7375
  49.  
  50. // @connect *
  51. // @connect *://*.qidian.com/
  52.  
  53. // @include *://read.qidian.com/*,*.aspx
  54. // @include *://readbook.qidian.com/bookreader/*,*.html
  55. // @include *://read.qidian.com/BookReaderOld/*,*.aspx
  56. // @include *://read.qidian.com/BookReader/*,*.aspx
  57. // @exclude http://read.qidian.com/BookReader/vol,*,*.aspx
  58. // @include *://wwwploy.qidian.com/BookReader/*,*.aspx
  59. // @include *://free.qidian.com/Free/ReadChapter.aspx?*
  60. // @include *://vipreader.qidian.com/chapter/*/*
  61. // @include *://www.qdmm.com/BookReader/*,*.aspx
  62. // @include *://www.qdwenxue.com/BookReader/*,*.aspx
  63. // @include *://chuangshi.qq.com/read/bookreader/*.html*
  64. // @include *://chuangshi.qq.com/*bk/*/*-r-*.html*
  65. // @include *://yunqi.qq.com/*bk/*/*.html
  66. // @include *://dushu.qq.com/read.html?bid=*
  67. // @include *://www.jjwxc.net/onebook.php?novelid=*
  68. // @include *://my.jjwxc.net/onebook_vip.php?novelid=*&chapterid=*
  69. // @include *://book.zongheng.com/chapter/*/*.html
  70. // @include *://www.xxsy.net/books/*/*.html
  71. // @include *://book.zhulang.com/*/*.html
  72. // @include *://www.17k.com/chapter/*/*.html
  73. // @include *://mm.17k.com/chapter/*/*.html
  74. // @include *://www.kanxia.net/k/*/*/*.html
  75. // @include *://www.qingdi.com/files/article/html/*/*/*.html
  76. // @include *://www.xkzw.org/*/*.html
  77. // @include *://shouda8.com/*/*.html
  78. // @include *://novel.hongxiu.com/*/*/*.shtml
  79. // @include *://www.readnovel.com/novel/*.html
  80. // http://www.tianyabook.com/*/*.htm
  81.  
  82. // @include *://tieba.baidu.com/p/*
  83. // @include *://booklink.me/*
  84. // @include *://2.booklink.me/*
  85.  
  86. // booklink.me
  87. // @include *://www.shumil.com/*/*.html
  88. // @include *://www.wcxiaoshuo.com/wcxs-*-*/
  89. // @include *://www.xiaoshuoz.com/wcxs-*-*/
  90. // @include *://www.quledu.com/wcxs-*-*/
  91. // @include *://www.ranwen.cc/*/*/*/*.html
  92. // @include *://www.ranwen.net/files/article/*/*/*.html
  93. // @include *://www.ranwena.com/files/article/*/*/*.html
  94. // @include *://www.64mi.com/*/*/*/*.html
  95. // @include *://www.bxs.cc/*/*.html*
  96. // @include *://www.laishuwu.com/html/*/*/*.html
  97. // @include *://www.binhuo.com/html/*/*/*.html
  98. // @include *://www.haoqi99.com/haoqi99/*/*/*.shtml
  99. // @include *://www.shuhe.cc/*/*/
  100. // @include *://www.dudukan.net/html/*/*/*.html
  101. // @include *://www.hahawx.com/*/*/*.htm
  102. // @include *://www.zhuzhudao.com/txt/*/*/
  103. // @include *://www.zhuzhudao.cc/txt/*/*/
  104. // @include *://www.dahaomen.net/txt/*/*/
  105. // @include *://www.tadu.com/book/*/*/
  106. // @exclude *://www.tadu.com/book/*/toc/
  107. // @include *://www.aishoucang.com/*/*.html
  108. // @include *://www.wanshuba.com/Html/*/*/*.html
  109. // @include *://www.zhuishu.net/files/article/html/*/*/*.html
  110. // @include *://www.sqsxs.com/*/*/*.html*
  111. // @include *://www.caiwei.tw/html/*/*.html
  112. // @include *://www.hotsk.com/Html/Book/*/*/*.shtml
  113. // @include *://www.92to.com/*/*/*.html
  114. // @include *://www.qirexs.com/read-*-chapter-*.html
  115. // @include *://www.du00.com/read/*/*/*.html
  116. // @include *://www.qishuwu.com/*/*/
  117. // @include *://www.wandoou.com/book/*/*.html
  118. // @include *://www.6yzw.org/*/*.html
  119. // @include *://www.6yzw.com/*/*.html
  120. // @include *://www.daomengren.com/*/*.html
  121. // @include *://muyuge.com/*/*.html
  122. // @include *://www.muyuge.net/*/*.html
  123. // @include *://bbs.vyming.com/novel-read-*-*.html
  124. // @include *://www.9imw.com/novel-read-*-*.html
  125. // @include *://www.23zw.com/olread/*/*/*.html
  126. // @include *://www.50zw.com/book_*/*.html
  127. // @include *://www.xiangcunxiaoshuo.com/shu/*/*.html
  128. // @include *://www.lwxs520.com/books/*/*/*.html
  129. // @include *://m.lwxs520.com/books/*/*/*.html
  130. // @include *://www.lwxiaoshuo.com/*/*/*.html
  131. // @include *://www.zashu.net/books/*/*/*.html
  132. // @include *://www.yunlaige.com/html/*/*/*.html
  133. // @include *://www.cfwx.net/files/article/html/*/*/*.html
  134. // @include *://www.qiuwu.net/html/*/*/*.html
  135. // @include *://www.fengwu.org/html/*/*/*.html
  136. // @include *://www.wenxue8.org/html/*/*/*.html
  137.  
  138. // @include *://www.xs84.com/*_*/*
  139. // @include *://www.geiliwx.com/GeiLi/*/*/*.shtml*
  140. // @include *://www.123yq.com/read/*/*/*.shtml
  141. // @include *://www.123yq.org/read/*/*/*.shtml
  142. // @include *://www.dhzw.com/book/*/*/*.html
  143. // *://www.du00.cc/read/*/*/*.html
  144. // @include *://www.aszw.com/book/*/*/*.html
  145. // @include *://www.xsbashi.com/*_*/
  146. // @include *://www.vodtw.com/Html/Book/*/*/*.html
  147. // @include *://www.fhxs.com/read/*/*/*.shtml
  148. // @include *://www.snwx.com/book/*/*/*.html
  149.  
  150. // www.sodu.so
  151. // @include *://www.jiaodu8.com/*/*/*/*.html
  152. // @include *://www.fktxt.com/book/*/*.html
  153. // @include *://www.186s.cn/files/article/html/*/*/*.html
  154. // @include *://www.6xs.cn/xs/*/*/*.html
  155. // @include *://www.chaojiqiangbing.com/book/*/*/*.html
  156. // @include *://book.moka123.com/book/*/*/*.html
  157. // @include *://www.suimeng.com/files/article/html/*/*/*.html
  158. // @include *://www.hao662.com/haoshu/*/*/*.html
  159.  
  160. //www.verydu.net
  161. // http://www.yawen8.com/*/*/*.html
  162. // @include *://www.tsxs.cc/files/article/html/*/*/*.html
  163. // @include *://www.ziyuge.com/*/*/*/*/*.html
  164.  
  165. // 其它网站
  166. // @include *://book.sfacg.com/Novel/*/*/*/
  167. // @include *://www.7dsw.com/book/*/*/*.html
  168. // @include *://www.d586.com/*/*/
  169. // @include *://www.bookgew.com/Html/Book/*/*/*.htm
  170. // @include *://read.shuhaha.com/Html/Book/*/*/*.html
  171. // @include *://www.shuhaha.com/Html/Book/*/*/*.html
  172. // @include *://www.biqi.me/files/article/html/*/*/*.html
  173. // @include *://www.ttzw.com/book/*/*.html
  174. // @include *://www.uukanshu.com/*/*/*.html
  175. // @include *://www.uukanshu.net/*/*/*.html
  176. // @include *://www.173ed.com/read/*/*.html
  177. // @include *://www.a240.com/read/*/*.html
  178. // @include *://www.zhuishu.com/*/*.html
  179. // @include *://www.shuangde.cc/*/*.html
  180. // @include *://www.shenmaxiaoshuo.com/ml-*-*/
  181. // @include *://www.86kankan.com/read/*/*.html
  182. // @include *://www.fkzww.com/*/*/*.html
  183. // @include *://www.151kan.com/*/*/*/*.html
  184. // @include *://www.bookabc.net/*/*/*.html
  185. // @include *://www.xshuotxt.com/*/*/*/*.html
  186. // @include *://www.doulaidu.com/*/*/*.html
  187. // @include *://www.d586.com/*/*/
  188. // @include *://www.kanshu.la/book/*/*html
  189. // @include *://www.wtcxs.com/files/article/html/*/*/*.html
  190. // @include *://www.5du5.com/book/*/*/*.html
  191. // @include *://book.kanunu.org/*/*/*.html
  192. // @include *://www.kanunu8.com/book*/*.html
  193. // @include *://paitxt.com/*/*/*.html
  194. // @include *://www.shunong.com/yuedu/*/*/*.html
  195. // @include *://book.yayacms.com/*/book_*_*.html
  196. // @include *://www.yqhhy.cc/*/*/*.html
  197. // @include *://www.nuoqiu.com/static/*/*.html
  198. // @include *://www.17yue.com/*/*/*.html
  199. // @include *://dukeba.com/book/*/*/*.shtml
  200. // @include *://www.wenchangshuyuan.com/html/*/*/*.html
  201. // @include *://www.pofeng.net/xiaoshuo/*/*.html
  202. // @include *://www.epzww.com/book/*/*
  203. // @include *://*.xiaoshuokan.com/haokan/*/*.html
  204. // @include *://www.wobudu.com/*/*.html
  205. // @include *://www.qb5.com/xiaoshuo/*/*/*.html
  206. // @include *://www.x23us.com/html/*/*/*.html
  207. // @include *://www.23us.com/html/*/*/*.html
  208. // @include *://www.23us.cc/html/*/*/*.html
  209. // @include *://www.23wx.com/html/*/*/*.html
  210. // @include *://www.xs222.com/html/*/*/*.html
  211. // @include *://www.bixiage.com/*/*/*/*.html
  212. // @include *://www.ranwenxiaoshuo.com/files/article/html/*/*/*.html
  213. // @include *://www.ranwenxiaoshuo.com/*/*-*-*.html
  214. // @include *://www.bjxiaoshuo.com/bjxs-*-*/
  215. // @include *://www.59shuku.com/xiaoshuo/*/*.htm
  216. // @include *://www.16kbook.org/Html/Book/*/*/*.shtml
  217. // @include *://www.dixiaoshuo.com/Html/*/*.html
  218. // @include *://www.nieshu.com/Book/*/*/*.shtml
  219. // @include *://www.tlxsw.com/files/article/html/*/*/*.html
  220. // @include *://www.1kanshu.com/files/article/html/*/*/*.html
  221. // @include *://www.uutxt.org/book/*/*/*.html
  222. // @include *://www.5800.cc/*/*/*/*.html
  223. // @include *://www.biquge.com/*/*.html
  224. // @include *://www.biqudu.com/*/*.html
  225. // @include *://www.biquge.la/book/*/*.html
  226. // @include *://www.biquge.com.tw/*/*.html
  227. // @include *://www.biquge.tw/*_*/*.html
  228. // @include *://www.biqugezw.com/*/*.html
  229. // @include *://www.bequgezw.com/*/*/*.html
  230. // @include *://www.biquzi.com/*_*/*.html
  231. // @include *://www.qududu.com/book/*/*/*.html
  232. // @include *://www.free97.cn/book/*/*/*.html
  233. // @include *://www.122s.com/book/*/*.html
  234. // @include *://www.123du.net/dudu-*/*/*.html
  235. // @include *://www.123du.cc/dudu-*/*/*.html
  236. // @include *://www.123du.net/book/*/*.html
  237. // @include *://www.hwafa.com/*/*.html
  238. // @include *://www.qmshu.com/html/*/*/*.html
  239. // @include *://dlzw.cc/article-*-*.html
  240. // @include *://www.shushu5.com/read/*/*.html
  241. // @include *://www.xiaoyanwenxue.com/files/article/html/*/*/*.html
  242. // @include *://www.3gsc.com.cn/bookcon/*_*_*
  243. // @include *://www.bj-ibook.cn/book/*/*/*.htm
  244. // @include *://www.baoliny.com/*/*.html
  245. // @include *://www.dajiadu.net/files/article/html/*/*/*.html
  246. // @include *://www.yankuai.com/files/article/html/*/*/*.html
  247. // @include *://www.docin.net/*/*.html
  248. // @include *://www.dushuge.net/html/*/*/*.html
  249. // @include *://www.xunshu.org/xunshu/*/*/*.html
  250. // @include *://www.moneyren.com/book/*/*/*.shtml
  251. // @include *://wemaxfilipino.com/*/*/*.html
  252. // @include *://www.85618892.cn/xiaoshuo/*/*/*.shtml
  253. // @include *://www.bookba.net/Html/Book/*/*/*.html
  254. // @include *://www.moksos.com/*/*/*.html
  255. // @include *://dudu8.net/novel/*/*/*.html
  256. // @include *://www.dawenxue.net/html/*/*/*.html
  257. // @include *://www.yanmoxuan.org/book/*/*/*.html
  258. // @include *://www.duyidu.com/xiaoshuo/*/*/*.html
  259. // @include *://www.69zw.com/xiaoshuo/*/*/*.html
  260. // @include *://www.kan7.com/xiaoshuo/*/*/*.html
  261. // @include *://www.laishu.com/book/*/*/*.shtml
  262. // @include *://www.bxwx.org/b/*/*/*.html
  263. // @include *://www.bxzw.org/*/*/*/*.shtml
  264. // @include *://www.360118.com/html/*/*/*.html
  265. // @include *://www.59to.com/files/article/xiaoshuo/*/*/*.html
  266. // @include *://www.dyzww.com/cn/*/*/*.html
  267. // @include *://www.9wh.net/*/*/*.html
  268. // @include *://www.luoqiu.net/html/*/*/*.html
  269. // @include *://www.luoqiu.com/html/*/*/*.html
  270. // @include *://www.epzw.com/files/article/html/*/*/*.html
  271. // @include *://www.dashubao.co/book/*/*/*.html
  272. // @include *://b.faloo.com/p/*/*.html
  273. // @include *://www.baikv.com/*/*.html
  274. // @include *://www.66721.com/*/*/*.html
  275. // @include *://www.3dllc.com/html/*/*/*.html
  276. // @include *://www.xstxt.com/*/*/
  277. // @include *://www.zzzcn.com/3z*/*/
  278. // @include *://www.zzzcn.com/modules/article/App.php*
  279. // @include *://www.nilongdao.com/book/*/*/*.html
  280. // @include *://xs321.net/*/*/
  281. // @include *://read.guanhuaju.com/files/article/html/*/*/*.html
  282. // @include *://www.book108.com/*/*/*.html
  283. // @include *://5ycn.com/*/*/*.html
  284. // @include *://www.zhaoxiaoshuo.com/chapter-*-*-*/
  285. // @include *://*zbzw.com/*/*.html
  286. // @include *://manghuangji.cc/*/*.html
  287. // @include *://www.aiqis.com/*/*.html
  288. // @include *://www.fftxt.net/book/*/*.html
  289. // @include *://www.5kwx.com/book/*/*/*.html
  290. // @include *://www.uuxiaoshuo.net/html/*/*/*.html
  291. // @include *://www.sanyyo.org/*.html
  292. // @include *://www.chinaisbn.com/*/*/*.html
  293. // @include *://www.caihongwenxue.com/Html/Book/*/*/*.html
  294. // @include *://www.shushuw.cn/shu/*/*.html
  295. // @include *://www.78xs.com/article/*/*/*.shtml
  296. // @include *://www.woaixiaoshuo.com/xiaoshuo/*/*/*.html
  297. // @include *://www.ty2016.com/book/*/*.html
  298. // @include *://wx.ty2016.com/*/*/*.html
  299. // @include *://www.my285.com/*/*/*/*.htm
  300. // @include *://www.5858xs.com/html/*/*/*.html
  301. // @include *://book.58xs.com/html/*/*/*.html
  302. // @include *://book.mihua.net/*/*/*/*.html
  303. // @include *://www.hjwzw.com/Book/Read/*,*
  304. // @include *://www.hjwzw.com/Book/Read/*_*
  305. // @include *://www.365essay.com/*/*.htm
  306. // @include *://www.gengxin8.com/read/*/*.html
  307. // @include *://www.365xs.org/books/*/*/*.html
  308. // @include *://www.wuruo.com/files/article/html/*/*/*.html
  309. // @include *://*.8shuw.net/book/*/*.html
  310. // @include *://www.pashuw.com/BookReader/*/*.html
  311. // @include *://read.shanwen.com/html/*/*/*.html
  312. // @include *://www.qqxs.cc/xs/*/*/*.html
  313. // @include *://www.69shu.com/txt/*/*
  314. // @include *://www.e8zw.com/book/*/*/*.html
  315. // @include *://www.8535.org/*/*/*.html*
  316. // @include *://www.yfzww.com/books/*/*/*.htm
  317. // @include *://www.lewen8.com/lw*/*.html
  318. // @include *://www.pinwenba.com/read/*/*.html
  319. // @include *://down1.qidian.com/bookall/*.htm*
  320. // @include *://www.77nt.com/*/*.html
  321. // @include *://www.quanbenba.com/yuedu/*/*/*.html
  322. // @include *://www.sto.cc/book-*-*.html
  323. // @include *://www.151xs.com/wuxiazuoxiong/*/chapter/*/
  324. // @include *://www.qududu.net/book/*/*/*.html
  325. // @include *://www.qingdou.cc/chapter*
  326. // @include *://www.shuyuewu.com/kan*
  327. // @include *://www.1553.net/*/*
  328. // @include *://www.269s.com/*/*/*
  329. // @include *://www.33yq.com/read/*/*/*.shtml
  330. // @include *://233yq.com/xiaoshuo/*.html
  331. // @include *://www.50zw.co/book_*/*.html
  332. // @include *://www.bqg5200.com/xiaoshuo/*/*/*.html
  333. // @include *://www.50zw.la/book_*/*.html
  334. // @include *://www.qu.la/book/*/*.html
  335. // @include *://www.luoqiu.com/read/*/*.html
  336. // @include *://www.54tushu.com/book_library/chaptershow/theId/*.html
  337. // @include *://www.snwx8.com/book/*/*/*.html
  338. // @include *://read.qidian.com/chapter/*
  339. // @include *://www.23zw.me/olread/*/*/*.html
  340. // @include *://www.piaotian.com/html/*/*/*.html
  341. // @include *://www.piaotian.net/html/*/*/*.html
  342. // @include *://www.dhzw.org/book/*/*/*.html
  343. // @include *://www.biqiuge.com/book/*/*.html
  344. // @include *://www.baquge.com/files/article/html/*/*/*.html
  345. // @include *://www.baquge.tw/files/article/html/*/*/*.html
  346. // @include *://www.qu.la/book/*/*.html
  347. // @include *://www.bxwx9.org/b/*/*/*.html
  348. // @include *://www.miaobige.com/*/*/*.html
  349. // @include *://www.52dsm.com/chapter/*/*.html
  350. // @include *://www.banfusheng.com/chapter/*/*.html
  351. // @include *://www.remenxs.com/du_*/*/
  352. // @include *://www.shuhai.com/read/*/*.html
  353. // @include *://www.hbooker.com/chapter/book_chapter_detail/*
  354. // @include *://www.mht.la/*/*/*.html
  355. // @include *://www.paomov.com/*/*/*.html
  356. // @include *://www.moyuanwenxue.com/xiaoshuo/*/*/*.htm
  357. // @include *://www.ggdown.com/modules/article/reader.php?aid=*
  358. // @include *://www.daizhuzai.com/*/*.html
  359. // @include *://www.mywenxue.com/xiaoshuo/*/*/*.htm
  360. // @include *://www.yueduyue.com/*/*.html
  361. // @include *://www.67shu.com/*/*/*.html
  362. // @include *://www.wangshu.la/books/*/*/*.html
  363. // @include *://www.23sw.net/*/*/*.html
  364. // @include *://www.ybdu.com/xiaoshuo/*/*/*.html
  365. // @include *://www.shudaizi.org/book/*/*.html
  366. // @include *://www.ymoxuan.com/book/*/*/*.html
  367. // @include *://www.67shu.com/*/*/*.html
  368. // @include *://www.bookxuan.com/*/*.html
  369. // @include *://www.2kxs.com/xiaoshuo/*/*.html
  370. // @include *://www.88dushu.com/xiaoshuo/*/*/*.html
  371. // @include *://www.wutuxs.com/html/*/*/*.html
  372. // @include *://www.23qb.com/book/*/*.html
  373. // @include *://www.biqu6.com/*/*.html
  374. // @include *://www.niepo.net/html/*/*/*.html
  375. // @include *://www.booktxt.net/*/*.html
  376. // @include *://www.aszw.org/book/*/*/*.html
  377. // @include *://www.xiashu.cc/*/*.html
  378. // @include *://www.lewenxiaoshuo.com/books/*/*.html
  379. // @include *://www.heihei66.com/*/*/*.html
  380. // @include *://www.111bz.net/*/*.html
  381. // @include *://www.biquge5200.com/*/*.html
  382. // @include *://www.biqukan.com/*_*/*.html
  383. // @include *://www.4xiaoshuo.com/*/*/*.html
  384. // @include *://www.woquge.com/*/*.html
  385. // @include *://www.lianzaishu.com/*/*.html
  386. // @include *://www.lucifer-club.com/chapter-*-*.html
  387. // @include *://www.011bz.com/*/*.html
  388.  
  389. // 移动版
  390. // @include *://wap.yc.ireader.com.cn/book/*/*/
  391. // @include *://m.jjwxc.net/book2/*/*
  392. // @include *://m.jjwxc.com/book2/*/*
  393. // @include *://wap.jjwxc.net/book2/*/*
  394. // @include *://wap.jjwxc.com/book2/*/*
  395. // @include *://wap.jjwxc.com/vip/*/*?ctime=*
  396. // @include *://wap.jjwxc.com/vip/*/*
  397. // @include *://wap.jjwxc.net/vip/*/*
  398. // @include *://m.jjwxc.net/vip/*/*
  399. // @include *://m.jjwxc.com/vip/*/*
  400.  
  401. // @exclude */List.htm
  402. // @exclude */List.html
  403. // @exclude */List.shtml
  404. // @exclude */index.htm
  405. // @exclude */index.html
  406. // @exclude */index.shtml
  407. // @exclude */Default.htm
  408. // @exclude */Default.html
  409. // @exclude */Default.shtml
  410.  
  411. // @run-at document-end
  412. // ==/UserScript==
  413.  
  414. // 其它设置
  415. const config = {
  416. lang: 'zh-CN',
  417.  
  418. soduso: false, // www.sodu.so 跳转
  419. // content_replacements: true, // 小说屏蔽字修复
  420. fixImageFloats: true, // 图片居中修正
  421. paragraphBlank: true, // 统一段落开头的空格为 2个全角空格
  422. end_color: "#666666", // 最后一页的链接颜色
  423. PRELOADER: true, // 提前预读下一页
  424.  
  425. xhr_time: 15 * 1000,
  426. download_delay: 0, // 毫秒。0 毫秒下载起点 vip 限时免费章节会被封
  427. dumpContentMinLength: 3, // 检测重复内容的最小行数
  428. };
  429.  
  430. var uiTrans = {
  431. "将小说网页文本转换为繁体。\n\n注意:内置的繁简转换表,只收录了简单的单字转换,启用本功能后,如有错误转换的情形,请利用脚本的自订字词取代规则来修正。\n例如:「千里之外」,会错误转换成「千里之外」,你可以加入规则「千里之外=千里之外」来自行修正。": "將小說網頁文字轉換為繁體。\n\n注意:內建的繁簡轉換表,只收錄了簡單的單字轉換,啟用本功能後,如有錯誤轉換的情形,請利用腳本的自訂字詞取代規則來修正。\n例如:「千里之外」,會錯誤轉換成「千裡之外」,你可以加入規則「千裡之外=千里之外」來自行修正。",
  432. "图片章节用夜间模式没法看,这个选项在启动时会自动切换到缺省皮肤": "圖片章節無法以夜間模式觀看,這個選項在啟動時會自動切換到預設佈景",
  433. "通过快捷键切换或在 Greasemonkey 用户脚本命令处打开设置窗口": "通過熱鍵切換或在 Greasemonkey 使用者腳本命令處開啟設定視窗",
  434. "隐藏后通过快捷键或 Greasemonkey 用户脚本命令处调用": "隱藏後通過熱鍵或 Greasemonkey 使用者腳本命令處調用",
  435. "一行一个,每行第一个 = 为分隔符\n需要刷新页面生效": "一行一條規則,每一行第一個 = 為分隔符\n(需重新載入頁面才能生效)",
  436. "错误:没有找到下一页的内容,使用右键翻到下一页": "錯誤:沒有找到下一頁的內容,使用右鍵翻到下一頁",
  437. "左键滚动,中键打开链接(无阅读模式)": "左鍵捲動畫面至該章節,中鍵開啟連結(無閱讀模式)",
  438. "请输入切换左侧章节列表的快捷键:": "請輸入切換左側章節列表的熱鍵:",
  439. "详见脚本代码的 Rule.specialSite": "詳見腳本代碼的 Rule.specialSite",
  440. "booklink.me 点击的网站强制启用": "booklink.me 點擊的網站強制啟用",
  441. "部分选项需要刷新页面才能生效": "部份選項需重新載入頁面才能生效",
  442. "取消本次设定,所有选项还原": "取消本次設定,所有選項還原",
  443. "不影响 booklink.me 的启用": "不影響 booklink.me 的啟用",
  444. "请输入打开设置的快捷键:": "請輸入開啟設定視窗的熱鍵:",
  445. "微软雅黑,宋体,黑体,楷体": "Microsoft YaHei,新細明體,PMingLiU,MingLiU,細明體,標楷體",
  446. "夜间模式的图片章节检测": "夜間模式的圖片章節檢測",
  447. "点击显示隐藏章节列表": "點此以顯示或隱藏章節列表",
  448. "添加下一页到历史记录": "加入下一頁到歷史記錄",
  449. "booklink 自动启用": "booklink 自動啟用",
  450. "Enter 键打开目录": "Enter 鍵開啟目錄",
  451. "隐藏左侧章节列表": "隱藏左側章節列表",
  452. "小说阅读脚本设置":"小說閱讀腳本設定",
  453. "已到达最后一页": "已到達最後一頁",
  454. "正在载入下一页": "正在載入下一頁",
  455. "通过快捷键切换": "通過熱鍵切換",
  456. "隐藏底部导航栏": "隱藏底部導航列",
  457. "隐藏左侧导航条": "隱藏左側章節列表彈出鈕",
  458. "主页链接没有找到": "未找到主頁連結",
  459. "自定义站点规则": "自訂網站規則",
  460. "自定义替换规则": "自訂字詞取代規則",
  461. "网页:转繁体": "網頁:轉繁體",
  462. "双击暂停翻页": "雙擊暫停翻頁",
  463. "隐藏设置按钮": "隱藏設定按鈕",
  464. "强制手动启用": "強制手動啟用",
  465. "调用阅读器": "調用閱讀器",
  466. "自定义样式": "自訂樣式",
  467. "界面语言": "介面語言",
  468. "打开目录": "開啟本書目錄頁",
  469. "自动翻页": "自動翻頁",
  470. "缺省皮肤": "預設佈景",
  471. "暗色皮肤": "暗色佈景",
  472. "夜间模式": "夜間模式",
  473. "夜间模式1": "夜間模式1",
  474. "夜间模式2": "夜間模式2",
  475. "橙色背景": "橙色背景",
  476. "绿色背景": "綠色背景",
  477. "绿色背景2": "綠色背景2",
  478. "蓝色背景": "藍色背景",
  479. "棕黄背景": "棕黃背景",
  480. "经典皮肤": "經典背景",
  481. "阅读模式": "閱讀模式",
  482. "调试模式": "偵錯模式",
  483. "反馈地址": "反饋與討論",
  484. "安静模式": "安靜模式",
  485. "√ 确认": "√ 確定",
  486. "X 取消": "X 取消",
  487. "上一页": "上一頁",
  488. "下一页": "下一頁",
  489. "状态": "狀態",
  490. "已经": "已經",
  491. "暂停": "暫停",
  492. "启用": "啟用",
  493. "退出": "離開",
  494. "测试": "測試",
  495. "距离": "距離",
  496. "加载": "載入",
  497. "字体": "字型",
  498. "行高": "行距",
  499. "行宽": "版面寬度",
  500. "目录": "目錄"
  501. };
  502.  
  503. if(!String.prototype.uiTrans){
  504. Object.defineProperty(String.prototype, 'uiTrans', {
  505. value: function(){
  506. var _this = this.valueOf(), key, regexp;
  507. if(config.lang !== 'zh-TW') return _this;
  508.  
  509. if(uiTrans.hasOwnProperty(_this)) return uiTrans[_this];
  510.  
  511. for (key in uiTrans) {
  512. regexp = new RegExp(key, 'g');
  513. _this = _this.replace(regexp, uiTrans[key]);
  514. }
  515. return _this;
  516. },
  517. enumerable: false
  518. });
  519. }
  520.  
  521. // 参考 https://github.com/madrobby/zepto/blob/master/src/detect.js
  522.  
  523. const ua = navigator.userAgent;
  524. const platform = navigator.platform;
  525.  
  526. const isFirefox = ua.match(/Firefox\/([\d.]+)/);
  527.  
  528. const isChrome = ua.match(/Chrome\/([\d.]+)/) || ua.match(/CriOS\/([\d.]+)/);
  529.  
  530. const isWindows = /Win\d{2}|Windows/.test(platform);
  531.  
  532. //------------------- 辅助函数 ----------------------------------------
  533. var nullFn = function() {};
  534.  
  535. // @require https://greasyfork.org/scripts/2599-gm-2-port-function-override-helper/code/GM%202%20port%20-%20Function%20Override%20Helper.js?version=184155
  536. // Check if is GM 2.x
  537. if (typeof window.exportFunction == 'undefined') {
  538. // For GM 1.x backward compatibility, should work.
  539. window.exportFunction = (function(foo, scope, defAs) {
  540. scope[defAs.defineAs] = foo;
  541. }).bind(unsafeWindow);
  542. }
  543.  
  544. var C;
  545.  
  546. function toggleConsole(debug) {
  547. if (debug) {
  548. C = console;
  549. } else {
  550. C = {
  551. log: nullFn,
  552. debug: nullFn,
  553. error: nullFn,
  554. group: nullFn,
  555. groupCollapsed: nullFn,
  556. groupEnd: nullFn,
  557. time: nullFn,
  558. timeEnd: nullFn,
  559. };
  560. }
  561. }
  562.  
  563. function L_getValue(key) { // 个别用户禁用本地存储会报错
  564. try {
  565. return localStorage.getItem(key);
  566. } catch (e) {}
  567. }
  568.  
  569. function L_setValue(key, value) {
  570. try {
  571. localStorage.setItem(key, value);
  572. } catch (e) {}
  573. }
  574.  
  575. function L_removeValue(key) {
  576. try {
  577. localStorage.removeItem(key);
  578. } catch (e) {}
  579. }
  580.  
  581.  
  582. function parseHTML(str) {
  583. var doc;
  584. try {
  585. // firefox and chrome 30+,Opera 12 会报错
  586. doc = new DOMParser().parseFromString(str, "text/html");
  587. } catch (ex) {}
  588.  
  589. if (!doc) {
  590. doc = document.implementation.createHTMLDocument("");
  591. doc.querySelector("html").innerHTML = str;
  592. }
  593. return doc;
  594. }
  595.  
  596. function toRE(obj, flag) {
  597. if (obj instanceof RegExp) {
  598. return obj;
  599. } else {
  600. return new RegExp(obj, (flag || 'ig'));
  601. }
  602. }
  603.  
  604. function toReStr(str) { // 处理字符串,否则可能会无法用正则替换
  605. return str.replace(/[()\[\]{}|+.,^$?\\*]/g, "\\$&");
  606. }
  607.  
  608. function wildcardToRegExpStr(urlstr) {
  609. if (urlstr.source) return urlstr.source;
  610. var reg = urlstr.replace(/[()\[\]{}|+.,^$?\\]/g, "\\$&").replace(/\*+/g, function(str){
  611. return str === "*" ? ".*" : "[^/]*";
  612. });
  613. return "^" + reg + "$";
  614. }
  615.  
  616. function getUrlHost(url) {
  617. var a = document.createElement('a');
  618. a.href = url;
  619. return a.host;
  620. }
  621.  
  622. // 模板
  623. $.nano = function(template, data) {
  624. return template.replace(/\{([\w\.]*)\}/g, function(str, key) {
  625. var keys = key.split("."),
  626. v = data[keys.shift()];
  627. try {
  628. for (var i = 0, l = keys.length; i < l; i++) v = v[keys[i]];
  629. } catch (e) {}
  630. return (typeof v !== "undefined" && v !== null) ? v : "";
  631. });
  632. };
  633.  
  634. // jQuery text 完全匹配. e.g. a:econtains('最新章节')
  635. $.expr[":"].econtains = function(obj, index, meta, stack) {
  636. return (obj.textContent || obj.innerText || $(obj).text() || "").toLowerCase() == meta[3].toLowerCase();
  637. };
  638.  
  639. /* jshint ignore: start */
  640.  
  641. function $x(aXPath, aContext) {
  642. var nodes = [];
  643. var doc = document;
  644. aContext = aContext || doc;
  645.  
  646. try {
  647. var results = doc.evaluate(aXPath, aContext, null,
  648. XPathResult.ANY_TYPE, null);
  649. var node;
  650. while (node = results.iterateNext()) {
  651. nodes.push(node);
  652. }
  653. } catch (ex) {}
  654.  
  655. return nodes;
  656. }
  657.  
  658. if (typeof String.prototype.startsWith != 'function') {
  659. String.prototype.startsWith = function(str) {
  660. return this.slice(0, str.length) == str;
  661. };
  662. }
  663.  
  664. if (typeof String.prototype.endsWith != 'function') {
  665. String.prototype.endsWith = function(str) {
  666. return this.slice(-str.length) == str;
  667. };
  668. }
  669.  
  670. if (!String.prototype.includes) {
  671. String.prototype.includes = function(search, start) {
  672. 'use strict';
  673. if (typeof start !== 'number') {
  674. start = 0;
  675. }
  676. if (start + search.length > this.length) {
  677. return false;
  678. } else {
  679. return this.indexOf(search, start) !== -1;
  680. }
  681. };
  682. }
  683.  
  684.  
  685. /*
  686. * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
  687. */
  688. jQuery.easing.jswing=jQuery.easing.swing,jQuery.extend(jQuery.easing,{def:"easeOutQuad",swing:function(a,b,c,d,e){return jQuery.easing[jQuery.easing.def](a,b,c,d,e)},easeInQuad:function(a,b,c,d,e){return d*(b/=e)*b+c},easeOutQuad:function(a,b,c,d,e){return-d*(b/=e)*(b-2)+c},easeInOutQuad:function(a,b,c,d,e){return(b/=e/2)<1?d/2*b*b+c:-d/2*(--b*(b-2)-1)+c},easeInCubic:function(a,b,c,d,e){return d*(b/=e)*b*b+c},easeOutCubic:function(a,b,c,d,e){return d*((b=b/e-1)*b*b+1)+c},easeInOutCubic:function(a,b,c,d,e){return(b/=e/2)<1?d/2*b*b*b+c:d/2*((b-=2)*b*b+2)+c},easeInQuart:function(a,b,c,d,e){return d*(b/=e)*b*b*b+c},easeOutQuart:function(a,b,c,d,e){return-d*((b=b/e-1)*b*b*b-1)+c},easeInOutQuart:function(a,b,c,d,e){return(b/=e/2)<1?d/2*b*b*b*b+c:-d/2*((b-=2)*b*b*b-2)+c},easeInQuint:function(a,b,c,d,e){return d*(b/=e)*b*b*b*b+c},easeOutQuint:function(a,b,c,d,e){return d*((b=b/e-1)*b*b*b*b+1)+c},easeInOutQuint:function(a,b,c,d,e){return(b/=e/2)<1?d/2*b*b*b*b*b+c:d/2*((b-=2)*b*b*b*b+2)+c},easeInSine:function(a,b,c,d,e){return-d*Math.cos(b/e*(Math.PI/2))+d+c},easeOutSine:function(a,b,c,d,e){return d*Math.sin(b/e*(Math.PI/2))+c},easeInOutSine:function(a,b,c,d,e){return-d/2*(Math.cos(Math.PI*b/e)-1)+c},easeInExpo:function(a,b,c,d,e){return 0==b?c:d*Math.pow(2,10*(b/e-1))+c},easeOutExpo:function(a,b,c,d,e){return b==e?c+d:d*(-Math.pow(2,-10*b/e)+1)+c},easeInOutExpo:function(a,b,c,d,e){return 0==b?c:b==e?c+d:(b/=e/2)<1?d/2*Math.pow(2,10*(b-1))+c:d/2*(-Math.pow(2,-10*--b)+2)+c},easeInCirc:function(a,b,c,d,e){return-d*(Math.sqrt(1-(b/=e)*b)-1)+c},easeOutCirc:function(a,b,c,d,e){return d*Math.sqrt(1-(b=b/e-1)*b)+c},easeInOutCirc:function(a,b,c,d,e){return(b/=e/2)<1?-d/2*(Math.sqrt(1-b*b)-1)+c:d/2*(Math.sqrt(1-(b-=2)*b)+1)+c},easeInElastic:function(a,b,c,d,e){var f=1.70158,g=0,h=d;return 0==b?c:1==(b/=e)?c+d:(g||(g=.3*e),h<Math.abs(d)?(h=d,f=g/4):f=g/(2*Math.PI)*Math.asin(d/h),-(h*Math.pow(2,10*(b-=1))*Math.sin((b*e-f)*2*Math.PI/g))+c)},easeOutElastic:function(a,b,c,d,e){var f=1.70158,g=0,h=d;return 0==b?c:1==(b/=e)?c+d:(g||(g=.3*e),h<Math.abs(d)?(h=d,f=g/4):f=g/(2*Math.PI)*Math.asin(d/h),h*Math.pow(2,-10*b)*Math.sin((b*e-f)*2*Math.PI/g)+d+c)},easeInOutElastic:function(a,b,c,d,e){var f=1.70158,g=0,h=d;return 0==b?c:2==(b/=e/2)?c+d:(g||(g=e*.3*1.5),h<Math.abs(d)?(h=d,f=g/4):f=g/(2*Math.PI)*Math.asin(d/h),1>b?-.5*h*Math.pow(2,10*(b-=1))*Math.sin((b*e-f)*2*Math.PI/g)+c:.5*h*Math.pow(2,-10*(b-=1))*Math.sin((b*e-f)*2*Math.PI/g)+d+c)},easeInBack:function(a,b,c,d,e,f){return void 0==f&&(f=1.70158),d*(b/=e)*b*((f+1)*b-f)+c},easeOutBack:function(a,b,c,d,e,f){return void 0==f&&(f=1.70158),d*((b=b/e-1)*b*((f+1)*b+f)+1)+c},easeInOutBack:function(a,b,c,d,e,f){return void 0==f&&(f=1.70158),(b/=e/2)<1?d/2*b*b*(((f*=1.525)+1)*b-f)+c:d/2*((b-=2)*b*(((f*=1.525)+1)*b+f)+2)+c},easeInBounce:function(a,b,c,d,e){return d-jQuery.easing.easeOutBounce(a,e-b,0,d,e)+c},easeOutBounce:function(a,b,c,d,e){return(b/=e)<1/2.75?d*7.5625*b*b+c:2/2.75>b?d*(7.5625*(b-=1.5/2.75)*b+.75)+c:2.5/2.75>b?d*(7.5625*(b-=2.25/2.75)*b+.9375)+c:d*(7.5625*(b-=2.625/2.75)*b+.984375)+c},easeInOutBounce:function(a,b,c,d,e){return e/2>b?.5*jQuery.easing.easeInBounce(a,2*b,0,d,e)+c:.5*jQuery.easing.easeOutBounce(a,2*b-e,0,d,e)+.5*d+c}});
  689.  
  690. /* jshint ignore: end */
  691.  
  692. // ===== 自定义站点规则 =====
  693.  
  694. const sites = [
  695. // 详细版规则示例。注:该网站已无法访问。
  696. {siteName: "泡书吧", // 站点名字... (可选)
  697. url: "^https?://www\\.paoshu8\\.net/Html/\\S+\\.shtm$", // // 站点正则... (~~必须~~)
  698.  
  699. // 获取标题
  700. titleReg: /(.*?)最新章节 [-_\\\/](.*?)[-_\/].*/, // 书籍标题、章节标题正则 (可选)
  701. titlePos: 0, // 书籍标题位置:0 或 1 (可选,默认为 0)
  702. titleSelector: "#title h1",
  703.  
  704. indexSelector: "a:contains('回目录')", // 首页链接 jQuery 选择器 (不填则尝试自动搜索)
  705. prevSelector: "a:contains('翻上页')", // 上一页链接 jQuery 选择器 (不填则尝试自动搜索)
  706. nextSelector: "a:contains('翻下页')", // 下一页链接 jQuery 选择器 (不填则尝试自动搜索)
  707.  
  708. // nDelay: 500, // 延迟0.5秒加载下一页
  709. // style: '', // 站点样式
  710.  
  711. // 获取内容
  712. contentSelector: "#BookText", // 内容 jQuery 选择器 (不填则尝试自动搜索)
  713. useiframe: false, // (可选)下一页加载是否使用 iframe
  714. // mutationSelector: "#chaptercontainer", // (可选)内容生成监视器
  715. // 对内容的处理
  716. contentHandle: false, // (可选)是否对内容进行特殊处理,诸如拼音字修复等,诸如起点等网站可禁用
  717. fixImage: true, // (可选),图片居中,不分大小
  718. contentReplace: /(\*W|(w|\(w).{10,25}(吧\*|)|\))|看小说就上|本书首发|泡.{1,6}吧|百度搜索阅读最新最全的小说|http:\/\/www.paoshu8.com\/|无弹窗/g, // 需要移除的内容正则 (可选)
  719. contentPatch: function(fakeStub){ // (可选)内容补丁。解决翻页是脚本的情况
  720. var $next = fakeStub.find('#LinkMenu');
  721. $next.html($next.html().replace(/<script>ShowLinkMenu.*?(<a.*?a>).*?(<a.*?a>).*?script>/,'$1$2') +
  722. '<a href=\'List.shtm\'>回目录</a>');
  723. }
  724. },
  725. {siteName: '起点新版-阅文',
  726. url: '^https?://(?:read|vipreader)\\.qidian\\.com/chapter/.*',
  727. exclude: ' /lastpage/',
  728. bookTitleSelector: '#bookImg',
  729. titleSelector: 'h3.j_chapterName',
  730.  
  731. prevSelector: '#j_chapterPrev',
  732. nextSelector: '#j_chapterNext',
  733. indexSelector: function(obj) {
  734. var url = obj.find(".chapter-control a:contains('目录')").attr('href');
  735. return url;
  736. },
  737.  
  738. contentSelector: '.read-content.j_readContent',
  739. contentRemove: '',
  740. contentReplace: [
  741. '手机用户请到m.qidian.com阅读。',
  742. '起点中文网www.qidian.com欢迎广大书友光临阅读,最新、最快、最火的连载作品尽在起点原创!.*'
  743. ],
  744. isVipChapter: function($doc) {
  745. if ($doc.find('.vip-limit-wrap').length) {
  746. return true;
  747. }
  748. },
  749. contentPatch: function($doc) {
  750. // 滚屏的方式无法获取下一页
  751. if ($doc.find('#j_chapterPrev').length === 0) {
  752. var $node = $doc.find('div[id^="chapter-"]');
  753. // 加上一页链接
  754. $('<div id="j_chapterPrev">')
  755. .attr('href', $node.attr('data-purl'))
  756. .appendTo($doc.find('body'));
  757. // 加下一页链接
  758. $('<div id="j_chapterNext">')
  759. .attr('href', $node.attr('data-nurl'))
  760. .appendTo($doc.find('body'));
  761. }
  762. }
  763. },
  764. // 特殊站点,需再次获取且跨域。添加 class="reader-ajax",同时需要 src, charset
  765. {siteName: '起点新版',
  766. url: '^https?://read\\.qidian\\.com/BookReader/.*\\.aspx',
  767. bookTitleSelector: '.story_title .textinfo a:nth-child(1)',
  768. titleSelector: '.story_title h1',
  769.  
  770. prevSelector: '#pagePrevRightBtn',
  771. nextSelector: '#pageNextRightBtn',
  772. indexSelector: function() {
  773. return location.href.replace(/,.*?\.aspx$/, '.aspx').replace('BookReaderNew', 'BookReader');
  774. },
  775.  
  776. mutationSelector: "#chaptercontainer", // 内容生成监视器
  777. mutationChildCount: 1,
  778. contentSelector: '#content, .bookreadercontent',
  779. contentRemove: 'a[href="http://www.qidian.com"]',
  780. contentReplace: [
  781. '手机用户请到m.qidian.com阅读。'
  782. ],
  783. contentPatch: function(fakeStub){
  784. fakeStub.find('script[src$=".txt"]').addClass('reader-ajax');
  785. },
  786. },
  787. {siteName: "起点中文、起点女生、起点文学",
  788. url: "^https?://(www|read|readbook|wwwploy|cga|big5ploy)\\.(qidian|qdmm|qdwenxue)\\.com/BookReader/.*",
  789. // titleReg: "小说:(.*?)(?:独家首发)/(.*?)/.*",
  790. titleSelector: "#lbChapterName",
  791. bookTitleSelector: ".page_site > a:last",
  792. // contentSelector: "#hdContent",
  793. nextUrl: function($doc){ // 为了避免起点某次改版后把1页拆成2页,然后造成重复载入第一页的情况
  794. var html = $doc.find('script:contains(nextpage=)').html();
  795. if (!html) return;
  796. var m = html.match(/nextpage='(.*?)'/);
  797. if (m) return m[1];
  798. },
  799. prevUrl: function($doc){
  800. var html = $doc.find('script:contains(prevpage=)').html();
  801. if (!html) return;
  802. var m = html.match(/prevpage='(.*?)'/);
  803. if (m) return m[1];
  804. },
  805. contentReplace: {
  806. "\\[img=(.*)\\]": "<p><img src='$1'></p><p>",
  807. "\\[+CP.*(http://file.*\\.jpg)\\]+": "<p><img src='$1'></p><p>",
  808. "\\[bookid=(\\d+),bookname=(.*?)\\]": "<a href='http://www.qidian.com/Book/$1.aspx'>$2</a>",
  809. "www.cmfu.com发布|起点中文网www.qidian.com欢迎广大书友光临阅读.*": "",
  810. '(<p>\\s+)?<a href="?http://www.(?:qidian|cmfu).com"?>起点中文网.*': '',
  811.  
  812. '([\\u4e00-\\u9fa5])[%¥]+([\\u4e00-\\u9fa5])': '$1$2', // 屏蔽词修正,例如:风%%骚
  813. },
  814. contentRemove: "span[id^='ad_'], .read_ma",
  815. contentPatch: function(fakeStub){
  816. fakeStub.find('script[src$=".txt"]').addClass('reader-ajax');
  817. },
  818. },
  819. {siteName: "起点中文网免费频道",
  820. url: "^https?://free\\.qidian\\.com/Free/ReadChapter\\.aspx",
  821. titleSelector: ".title > h3",
  822. bookTitleSelector: ".site_rect > a:last",
  823. contentSelector: "#chapter_cont, #content",
  824. contentRemove: ".nice_books",
  825. contentReplace: {
  826. "\\[img=(.*)\\]": "<p><img src='$1'></p><p>",
  827. "\\[+CP.*(http://file.*\\.jpg)\\]+": "<p><img src='$1'></p><p>",
  828. "\\[bookid=(\\d+),bookname=(.*?)\\]": "<a href='http://www.qidian.com/Book/$1.aspx'>$2</a>",
  829. "www.cmfu.com发布|起点中文网www.qidian.com欢迎广大书友光临阅读.*": "",
  830. '(<p>\\s+)?<a href="?http://www.(?:qidian|cmfu).com"?>起点中文网.*': ''
  831. },
  832. contentPatch: function(fakeStub) {
  833. fakeStub.find('#chapter_cont, #content > script:first').addClass('reader-ajax');
  834. }
  835. },
  836. {siteName: "创世中文网",
  837. url: "^https?://(?:chuangshi|yunqi)\\.qq\\.com/|^http://dushu\\.qq\\.com/read.html\\?bid=",
  838. bookTitleSelector: '.bookNav > a:last()',
  839. titleSelector: '.story_title > h1',
  840.  
  841. nextSelector: '#rightFloatBar_nextChapterBtn',
  842. prevSelector: '#rightFloatBar_preChapterBtn',
  843. indexSelector: function() {
  844. var m = location.href.match(/\/bk\/\w+\/(.*?)-r-\d+.html/);
  845. if (m) {
  846. return 'http://chuangshi.qq.com/bk/ls/' + m[1] + '-l.html';
  847. } else {
  848. return 'http://chuangshi.qq.com/bk/ls/' + unsafeWindow.bid + '-l.html';
  849. }
  850. },
  851.  
  852. contentSelector: ".bookreadercontent",
  853. contentHandle: false,
  854. mutationSelector: "#chaptercontainer", // 内容生成监视器,第一次运行用到,以后用下面的 getContent 函数
  855. mutationChildCount: 1,
  856. startFilter: function() {
  857. // 下一页需要提前加 1
  858. unsafeWindow.uuid = parseInt(unsafeWindow.uuid) + 1 + '';
  859. },
  860. getContent: function($doc, callback) { // this 指 parser
  861. function _getReadPageUrl(uuid) {
  862. if (!uuid) {
  863. return 'javascript:void(0);';
  864. }
  865. var url = location.href.replace(/[?|#].*/gi, '');
  866. return url.replace(/(\d)+\.html/, uuid + '.html');
  867. }
  868.  
  869. function getPageUrlHtml(preChapterUUID, nextChapterUUID) {
  870. var preReadUrl = _getReadPageUrl(preChapterUUID),
  871. nextReadUrl = _getReadPageUrl(nextChapterUUID);
  872.  
  873. return '<a id="rightFloatBar_preChapterBtn" href="' + preReadUrl + '">上一页</a>' +
  874. '<a id="rightFloatBar_nextChapterBtn" href="' + nextReadUrl + '">下一页</a>' + '\n';
  875. }
  876.  
  877. var done = function (data) {
  878. unsafeWindow.uuid = data.nextuuid; // 给下一页用
  879.  
  880. callback({
  881. html: getPageUrlHtml(data.preuuid, data.nextuuid) + data.Content
  882. });
  883. };
  884. exportFunction(done, unsafeWindow, { defineAs: "gm_mnr_cs_callback" });
  885.  
  886. unsafeWindow.CS.page.read.main.getChapterContent(unsafeWindow.bid, unsafeWindow.uuid,
  887. unsafeWindow.gm_mnr_cs_callback);
  888. },
  889. },
  890. {siteName: "纵横中文网",
  891. url: "^https?://book\\.zongheng\\.com/\\S+\\/\\d+\\.html$",
  892. contentHandle: false,
  893. // titleReg: "(.*?)-(.*)",
  894. titleSelector: "em[itemprop='headline']",
  895. bookTitleSelector: ".tc h2",
  896. contentSelector: '#readerFt',
  897. contentPatch: function(fakeStub){
  898. fakeStub.find('.watermark').remove();
  899. // 给第几章添加空格
  900. var chapterTitle = fakeStub.find(".tc > h2").text();
  901. var chapterTitle1 = fakeStub.find(".tc > h2 em").text();
  902. if(chapterTitle1) {
  903. chapterTitle = chapterTitle.replace(chapterTitle1, " ") + chapterTitle1;
  904. }
  905. fakeStub.find("title").text(
  906. fakeStub.find(".tc > h1").text() + "-" + chapterTitle
  907. );
  908. }
  909. },
  910. {siteName: "晋江文学网",
  911. url: /^https?:\/\/(www|my)\.jjwxc\.net\/onebook(|_vip)\.php\S*/,
  912. titleReg: /《(.*?)》.*[ˇ^](.*?)[ˇ^].*/,
  913. titlePos: 0,
  914. // titleSelector: 'h2',
  915. titleSelector: '#chapter_list > option:first',
  916. // bookTitleSelector: 'h1 .bigtext',
  917. indexSelector: ".noveltitle > h1 > a",
  918. contentSelector: '.noveltext',
  919. contentHandle: false,
  920. contentRemove: 'font[color], hr',
  921. contentPatch: function (fakeStub) {
  922. // 移除 h2 的标题
  923. fakeStub.find('div:has(>h2)').remove();
  924.  
  925. fakeStub.find('#six_list, #sendKingTickets').parent().remove();
  926. fakeStub.find("div.noveltext").find("div:first, h1").remove();
  927. },
  928. contentReplace: [
  929. '@无限好文,尽在晋江文学城'
  930. ]
  931. },
  932. {siteName: '晋江文学城_手机版',
  933. url: '^https?://(?:wap|m)\\.jjwxc\\.(?:net|com)/(?:book2|vip)/\\d+/\\d+',
  934. titleReg: /《(.*?)》.*[ˇ^](.*?)[ˇ^].*/,
  935. titlePos: 0,
  936. titleSelector: 'h2',
  937. contentSelector: 'div.grid-c > div > .b.module > div:first',
  938. },
  939. {siteName: "潇湘书院",
  940. url: "^https?://www\\.xxsy\\.net/books/.*\\.html",
  941. titleReg: "(.*?) (.*)",
  942. contentSelector: "#zjcontentdiv",
  943. nextSelector: "a[title='阅读下一章节']",
  944. contentHandle: false,
  945. contentReplace: "本书由潇湘书院首发,请勿转载!",
  946. contentPatch: function(fakeStub){
  947. fakeStub.find("title").text(fakeStub.find('meta[name="keywords"]').attr("content"));
  948. }
  949. },
  950. {siteName: "逐浪",
  951. url: /^https?:\/\/book\.zhulang\.com\/.*\.html/,
  952. titleReg: /(.*?)-(.*)/,
  953. contentSelector: "#readpage_leftntxt",
  954. contentHandle: false,
  955. contentPatch: function(fakeStub){
  956. var title = fakeStub.find(".readpage_leftnzgx a:first").text() + "-" +
  957. fakeStub.find(".readpage_leftntit").text();
  958. fakeStub.find('title').html(title);
  959. }
  960. },
  961. {siteName: "小说阅读网",
  962. url: "^https?://www\\.readnovel\\.com/novel/.*\\.html",
  963. titleSelector: ".bgtop > h1",
  964. bookTitleSelector: ".nownav > a:eq(4)",
  965. contentSelector: "#article, .zhangjie",
  966. contentRemove: "div[style], .miaoshu, .zhichi, .bottomAdbanner",
  967. contentPatch: function(fakeStub) {
  968. // 删除标题不需要的部分
  969. fakeStub.find(".bgtop > h1 > span").remove();
  970. }
  971. },
  972. // {siteName: "磨铁",
  973. // url: '^https?://www.motie.com/book/\\d+_\\d+',
  974. // contentSelector: '.page-content'
  975. // },
  976.  
  977. {siteName: "百度贴吧(手动启用)",
  978. enable: false,
  979. url: /^https?:\/\/tieba\.baidu.com\/p\//,
  980. titleSelector: "h1.core_title_txt",
  981. bookTitleSelector: ".card_title_fname",
  982. nextSelector: false,
  983. indexSelector: 'a.card_title_fname',
  984. prevSelector: false,
  985.  
  986. contentSelector: "#j_p_postlist",
  987. contentRemove: "#sofa_post, .d_author, .share_btn_wrapper, .core_reply, .j_user_sign",
  988. style: ".clear { border-top:1px solid #cccccc; margin-bottom: 50px; visibility: visible !important;}", // 显示楼层的分割线
  989. },
  990. // {siteName: "天涯在线书库(部分支持)",
  991. // url: /www\.tianyabook\.com\/.*\.htm/,
  992. // titleSelector: ".max, h1:first",
  993. // bookTitleSelector: "td[width='70%'] > a[href$='index.htm']",
  994. // contentSelector: "div > span.middle, #texts",
  995. // contentHandle: false,
  996. // },
  997. {siteName: "天涯书库",
  998. url: /www\.ty2016\.com\/.+\.html$/,
  999. titleSelector: "h1",
  1000. bookTitleSelector: ".crumb a[href='./']",
  1001.  
  1002. indexSelector: "td a[href='./']",
  1003.  
  1004. contentSelector: "#main",
  1005. contentRemove: '.crumb, table',
  1006. contentHandle: false,
  1007. },
  1008.  
  1009. // {siteName: "易读",
  1010. // url: "^https?://www.yi-see.com/read_\\d+_\\d+.html",
  1011. // contentSelector: 'table[width="900px"][align="CENTER"]'
  1012. // },
  1013. {siteName: "燃文",
  1014. url: /^https?:\/\/www\.(?:ranwena?\.(cc|net|com)|64mi\.com)\/.*\.html$/,
  1015. titleReg: /(.*?)-(.*?)-燃文/,
  1016. contentSelector: "#oldtext, #contents",
  1017. contentRemove: "div[style], script",
  1018. contentReplace: [
  1019. /\((&nbsp;)*\)/g,
  1020. /最快更新78小说|\(?百度搜.\)|访问下载tXt小说|百度搜\|索|文\|学|文学全文.字手打|\((&nbsp;)+|牛过中文..hjsm..首发.转载请保留|\[本文来自\]|♠思♥路♣客レ|※五月中文网 5y ※|无错不跳字|最快阅读小说大主宰.*|跟我读H-u-n 请牢记|非常文学|关闭&lt;广告&gt;|w w.*|”娱乐秀”|更多精彩小[说說].*|高速更新/g,
  1021. /[\(\*◎]*(百度搜)?文.?[學学].?[馆館][\)\*)]*|\(百度搜\)/g,
  1022. /提供无弹窗全文字在线阅读.*|高速首发.*如果你觉的本章节还不错的话.*/g,
  1023. /书网∷更新快∷无弹窗∷纯文字∷.t!。/g,
  1024. /一秒记住,本站为您提供热门小说免费阅读。/g,
  1025. /\(更新速度最快记住即可找到\)|芒果直播网|.mgzhibo .|去 读 读|看小说就到/g,
  1026. '火然\\?\\?\\? \\?文&nbsp;&nbsp;w\\?ww.ranwena.com',
  1027. ]
  1028. },
  1029. {siteName: "燃文小说网",
  1030. url: "^https?://www\\.ranwenxiaoshuo\\.com/files/article/html/\\d+/\\d+/\\d+\\.html|http://www\\.ranwenxiaoshuo\\.com/\\w+/\\w+-\\d+-\\d+\\.html",
  1031. titleReg: /(.*?)最新章节(.*?)在线阅读.*/,
  1032. contentSelector: "#fontsize",
  1033. contentReplace: "天才一秒记住[\\s\\S]+为您提供精彩小说阅读。",
  1034. },
  1035. {siteName: "燃文小说",
  1036. url: "^https?://www\\.ranwen\\.net/files/article/\\d+/\\d+/\\d+\\.html",
  1037. titleReg: "(\\S+) (.*) - 燃文小说",
  1038. contentReplace: "\\(.*燃文小说.*\\)|【 注册会员可获私人书架,看书更方便!永久地址: 】 "
  1039. },
  1040. {siteName: "无错小说网",
  1041. url: /^https?:\/\/www\.(?:wcxiaoshuo|xiaoshuoz|quledu)\.com\/wcxs[-\d]+\//,
  1042. titleReg: /(.*?)最新章节.*?-(.*?)-.*/,
  1043. titlePos: 1,
  1044. nextSelector: "a#htmlxiazhang",
  1045. prevSelector: "a#htmlshangzhang",
  1046. indexSelector: "a#htmlmulu",
  1047. contentReplace: [
  1048. 'ilo-full-src="\\S+\\.jpg" ',
  1049. {
  1050. '(<center>)?<?img src..(http://www.wcxiaoshuo.com)?(/sss/\\S+\\.jpg).(>| alt."\\d+_\\d+_\\d*\\.jpg" />)(</center>)?': '$3',
  1051. "/sss/da.jpg": "打", "/sss/maws.jpg": "吗?", "/sss/baw.jpg": "吧?", "/sss/wuc.jpg": "无", "/sss/maosu.jpg": ":“", "/sss/cuow.jpg": "错", "/sss/ziji.jpg": "自己", "/sss/shenme.jpg": "什么", "/sss/huiqub.jpg": "回去", "/sss/sjian.jpg": "时间", "/sss/zome.jpg": "怎么", "/sss/zhido.jpg": "知道", "/sss/xiaxin.jpg": "相信", "/sss/faxian.jpg": "发现", "/sss/shhua.jpg": "说话", "/sss/dajiex.jpg": "大姐", "/sss/dongxi.jpg": "东西", "/sss/erzib.jpg": "儿子", "/sss/guolair.jpg": "过来", "/sss/xiabang.jpg": "下班", "/sss/zangfl.jpg": "丈夫", "/sss/dianhua.jpg": "电话", "/sss/huilaim.jpg": "回来", "/sss/xiawu.jpg": "下午", "/sss/guoquu.jpg": "过去", "/sss/shangba.jpg": "上班", "/sss/mingtn.jpg": "明天", "/sss/nvrenjj.jpg": "女人", "/sss/shangwo.jpg": "上午", "/sss/shji.jpg": "手机", "/sss/xiaoxinyy.jpg": "小心", "/sss/furene.jpg": "夫人", "/sss/gongzih.jpg": "公子", "/sss/xiansg.jpg": "先生", "/sss/penyouxi.jpg": "朋友", "/sss/xiaoje.jpg": "小姐", "/sss/xifup.jpg": "媳妇", "/sss/nvxudjj.jpg": "女婿", "/sss/xondi.jpg": "兄弟", "/sss/lagong.jpg": "老公", "/sss/lapo.jpg": "老婆", "/sss/meimeid.jpg": "妹妹", "/sss/jiejiev.jpg": "姐姐", "/sss/jiemeiv.jpg": "姐妹", "/sss/xianggx.jpg": "相公", "/sss/6shenumev.jpg": "什么", "/sss/cuoaw.jpg": "错", "/sss/fpefnyoturxi.jpg": "朋友", "/sss/vfsjgigarn.jpg": "时间", "/sss/zzhiedo3.jpg": "知道", "/sss/zibjib.jpg": "自己", "/sss/qdonglxi.jpg": "东西", "/sss/hxiapxint.jpg": "相信", "/sss/fezrormre.jpg": "怎么", "/sss/nvdrfenfjfj.jpg": "女人", "/sss/jhiheejeieev.jpg": "姐姐", "/sss/xdifagojge.jpg": "小姐", "/sss/gggugolgair.jpg": "过来", "/sss/maoashu.jpg": ":“", "/sss/gnxnifawhu.jpg": "下午", "/sss/rgtugoqgugu.jpg": "过去", "/sss/khjukilkaim.jpg": "回来", "/sss/gxhigfadnoxihnyy.jpg": "小心", "/sss/bkbskhhuka.jpg": "说话", "/sss/xeieavnfsg.jpg": "先生", "/sss/yuhhfuiuqub.jpg": "回去", "/sss/pdianphua.jpg": "电话", "/sss/fabxianr.jpg": "发现", "/sss/feilrpto.jpg": "老婆", "/sss/gxronfdri.jpg": "兄弟", "/sss/flfaggofng.jpg": "老公", "/sss/tymyigngtyn.jpg": "明天", "/sss/dfshfhhfjfi.jpg": "手机", "/sss/gstjhranjgwjo.jpg": "上午", "/sss/fmgeyimehid.jpg": "妹妹", "/sss/gxgihftutp.jpg": "媳妇", "/sss/cerztifb.jpg": "儿子", "/sss/gfxgigagbfadng.jpg":"下班", "/sss/gstjhranjg.jpg":"下午", "/sss/hjeirerm6eihv.jpg": "姐妹", "/sss/edajihexr.jpg": "大姐", "/sss/wesfhranrrgba.jpg": "上班", "/sss/gfognggzigh.jpg": "公子", "/sss/frurtefne.jpg": "夫人", "/sss/fzagnggfbl.jpg": "丈夫", "/sss/nvdxfudfjfj.jpg": "女婿", "/sss/xdidafnggx.jpg": "相公", "/sss/zenme.jpg": "怎么", "/sss/gongzi.jpg": "公子", "/sss/ddefr.jpg": "",
  1052. },
  1053. ".*ddefr\\.jpg.*|无(?:错|.*cuoa?w\\.jpg.*)小说网不[少跳]字|w[a-z\\.]*om?|.*由[【无*错】].*会员手打[\\s\\S]*",
  1054. "是 由",
  1055. "无错不跳字|无广告看着就是爽!|一秒记住.*|全文免费阅读.*|8 9 阅阅 读 网|看小说最快更新|“小#说看本书无广告更新最快”",
  1056. "[\\x20-\\x7e》]?无(?:.|&gt;)错.小说.{1,2}[Ww]+.*?[cC][oO][mM]",
  1057. "<无-错>",
  1058. "—无—错—小说",
  1059. "\\+无\\+错\\+",
  1060. "&amp;无&amp;错&amp;小说",
  1061. "无错小说 www.quled[Uu].com",
  1062. ],
  1063. contentPatch: function(fakeStub){
  1064. // 去除内容开头、结尾的重复标题
  1065. var title = fakeStub.find("#htmltimu").text().replace(/\s+/, "\\s*");
  1066. var content = fakeStub.find("#htmlContent");
  1067. content.find("div[align='center']").remove();
  1068. if(title.match(/第\S+章/)){
  1069. content.html(content.html().replace(new RegExp(title), "").replace(new RegExp(title), ""));
  1070. }
  1071. }
  1072. },
  1073. {siteName: '凤舞文学网',
  1074. url: '^https?://www\\.wenxue8\\.org/html/\\d+/\\d+/\\d+\\.html',
  1075. contentReplace: [
  1076. {
  1077. '<img src="/keywd/R43.gif">':'爱', '<img src="/keywd/A13.gif">': '情', '<img src="/keywd/D10.gif">': '床',
  1078. '<img src="/keywd/Y19.gif">': '奸', '<img src="/keywd/H21.gif">': '屁', '<img src="/keywd/Z23.gif">': '逼',
  1079. '<img src="/keywd/G42.gif">': '身', '<img src="/keywd/Y2.gif">':'性', '<img src="/keywd/D32.gif">':'热',
  1080. '<img src="/keywd/I44.gif">':'挺', '<img src="/keywd/H30.gif">':'贱', '<img src="/keywd/H25.gif">':'荡',
  1081. '<img src="/keywd/V7.gif">':'肉', '<img src="/keywd/O22.gif">':'吮', '<img src="/keywd/H9.gif">':'春',
  1082. '<img src="/keywd/K36.gif">':'日', '<img src="/keywd/O15.gif">':'胸', '<img src="/keywd/S31.gif">':'欲',
  1083. '<img src="/keywd/F20.gif">':'射', '<img src="/keywd/N12.gif">':'禁', '<img src="/keywd/R26.gif">':'殿',
  1084. '<img src="/keywd/X6.gif">':'诱', '<img src="/keywd/U46.gif">': '娇',
  1085. '<img src="/keywd/M24.gif">': '操', '<img src="/keywd/B4.gif">':'骚', '<img src="/keywd/O3.gif">':'阴',
  1086. }
  1087. ]
  1088. },
  1089. {siteName: "书迷楼",
  1090. url: /^https?:\/\/www\.shumil\.(?:co|us|com)\/.*html$/,
  1091. titleReg: /(.*) (.*?) 书迷楼/,
  1092. titlePos: 1,
  1093. contentSelector: "#content",
  1094. contentRemove: 'a, center',
  1095. contentReplace: [
  1096. 'div lign="ener"&gt;|.*更多章节请到网址隆重推荐去除广告全文字小说阅读器',
  1097. '起点中文网www.qidian.com欢迎广大书.*',
  1098. '书迷楼最快更新.*',
  1099. '更新最快最稳定',
  1100. '\\(\\.\\)R?U',
  1101. {'<p>\\?\\?': '<p>'},
  1102. '\\(www.\\)',
  1103. '章节更新最快',
  1104. '-乐-读-小-说--乐读x-',
  1105. '《乐》《读》小说.乐读.Com',
  1106. '纯文字在线阅读本站域名手机同步阅读请访问',
  1107. '-优-优-小-说-更-新-最-快-www.uuxs.cc-',
  1108. '\\(本章免费\\)',
  1109. '请大家搜索(书迷楼)看最全!更新最快的小说',
  1110. '书迷楼www.shumilou.co',
  1111. 'shumil.com',
  1112. '书迷楼 ()',
  1113. '书迷楼',
  1114. ],
  1115. fixImage: true,
  1116. contentPatch: function(fakeStub){
  1117. fakeStub.find("#content").find("div.title:last")
  1118. .appendTo(fakeStub.find('body'));
  1119. fakeStub.find("#content").find("div.title, p > b, div[style]").remove();
  1120. }
  1121. },
  1122. {siteName: "冰火中文",
  1123. url: /^https?:\/\/www\.binhuo\.com\/html\/[\d\/]+\.html$/,
  1124. titleReg: /(.*?)最新章节,(.*?)-.*/,
  1125. fixImage: true,
  1126. contentRemove: 'font[color="red"]',
  1127. contentReplace: {
  1128. "&lt;冰火#中文.*|冰火中文&nbsp;(www.)?binhuo.com(?:【首发】|)|冰.火.中文|绿色小说|lvsexs|冰火中文": "",
  1129. "LU5.coM|lU5.com|LU5.com":"",
  1130. "([^/])www\\.binhuo\\.com(?:\\.com|)": "$1",
  1131. "\\(.*?平南文学网\\)": "",
  1132. },
  1133. contentPatch: function(fakeStub){
  1134. fakeStub.find("#BookText").append(fakeStub.find("img.imagecontent"));
  1135. }
  1136. },
  1137. {siteName: "百晓生",
  1138. url: /^https?:\/\/www\.bxs\.cc\/\d+\/\d+\.html/,
  1139. titleReg: /(.*?)\d*,(.*)/,
  1140. contentRemove: 'a, #txtright',
  1141. contentReplace: [
  1142. /一秒记住【】www.zaidu.cc,本站为您提供热门小说免费阅读。/ig,
  1143. /(文&nbsp;學馆w&nbsp;ww.w&nbsp;xguan.c&nbsp;om)/ig,
  1144. /(百晓生更新最快最稳定\)/g,
  1145. /\((?:&nbsp;)*(?:无弹窗)?全文阅读\)/ig,
  1146. /\[<a.*?首发\[百晓生\] \S+/ig,
  1147. /高速首发.*本章节是地址为/ig,
  1148. /\/\/(?:&nbsp;|访问下载txt小说|高速更新)+\/\//ig,
  1149. /(www\.)?bxs\.cc|www\.bxs(\.com)?/ig,
  1150. /百晓生.不跳字|不跳字。|更新快纯文字/ig,
  1151. /\.\[,!\]/ig,
  1152. /(未完待续&nbsp;http:\/\/www.Bxs.cc&nbsp;89免费小说阅《百晓生文学网》)/g,
  1153. /〖百晓生∷.*〗|《?百晓生文学网》?|最快阅读小说大主宰,尽在百晓生文学网.*|ww.x.om|欢迎大家来到.*?bxs\.cc|百晓生阅读最新最全的小说.*|百晓生网不少字|站长推荐.*|文字首发|百.晓.生.|关闭.*广告.*|飘天文学|本站域名就是.*|\(.{0,5}小说更快更好.{0,5}\)|(请在)?百度搜索.*|一秒记住.*为您提供精彩小说阅读.|百晓生|¤本站网址:¤|\/\/&nbsp;访问下载txt小说\/\/◎◎|纯站点\\".*值得收藏的/ig,
  1154. /文[学學][馆館]|www\.biquge\.cc|(http:\/\/)?www\.Bxs\.cc|(请牢记)?soudu.org/ig,
  1155. /请搜索,小说更好更新更快!|最快文字更新无弹窗无广|\(即可找到本站\)|无广告看着就是爽!|更多全本txt小说请到下载|∷更新快∷∷纯文字∷/ig,
  1156. /永久网址,请牢记!/ig,
  1157. /&nbsp;&gt;<\/p>/ig,
  1158. ],
  1159. },
  1160. {siteName: "浩奇文学网",
  1161. url: /^https?:\/\/www\.haoqi99\.com\/.*\.shtml$/,
  1162. titleReg: /^(.*?)--(.*?)-/,
  1163. },
  1164. {siteName: "书河小说网",
  1165. url: /^https?:\/\/www\.shuhe\.cc\/\d+\/\d+/,
  1166. titleReg: "([^\\d]+)\\d*,(.*?)_",
  1167. contentSelector: "#TXT",
  1168. contentReplace: /一秒记住.*为您提供精彩小说阅读.|\{请在百度搜索.*首发阅读\}|(书河小说网.*?无弹窗)|wxs.o|ww.x.om|[\[【\(].{1,30}[\]\)】]|ff37;.*|书河小说网高速首发.*|TXT下载|全文阅读|第一书河小说网|百书斋.*|首发来自书河小说网|本书最新章节|书河小说网/ig,
  1169. },
  1170. {siteName: "爱收藏",
  1171. url: /^https?:\/\/www\.aishoucang\.com\/\w+\/\d+\.html/,
  1172. titleReg: "(.*?)-(.*?)-爱收藏",
  1173. contentSelector: "#zhutone",
  1174. contentReplace: {
  1175. "<a[^>]*>(.*?)</a>": "$1",
  1176. ".爱收藏[^<]*": ""
  1177. }
  1178. },
  1179. {siteName: "木鱼哥",
  1180. url: /^https?:\/\/(www\.)?muyuge\.(com|net)\/\w+\/\d+\.html/,
  1181. titleSelector: "#yueduye h1",
  1182. bookTitleSelector: ".readerNav > li > a:last",
  1183. indexSelector: ".readerFooterPage a[title='(快捷:回车键)']",
  1184. // useiframe: true,
  1185. // mutationSelector: "#content",
  1186. // mutationChildCount: 1,
  1187. nextSelector: 'a:contains(下章)',
  1188. prevSelector: 'a:contains(上章)',
  1189. indexSelector: 'a:contains(目录)',
  1190. contentRemove: ".vote",
  1191. contentReplace: {
  1192. "<a[^>]*>(.*?)</a>": "$1",
  1193. "看更新最快的小说就搜索—— 木鱼哥——无弹窗,全文字": "",
  1194. "【看最新小说就搜索.*全文字首发】": "",
  1195. "<p>.*?无弹窗</p>":"",
  1196. "bb\\.king|【木&nbsp;鱼&nbsp;哥&nbsp;.*?】|【一秒钟记住本站:muyuge.com.*木鱼哥】":"",
  1197. "——推荐阅读——[\\s\\S]+": "",
  1198. "【\\s*木\\s*鱼\\s*哥.*?】":"",
  1199. "div&gt;|&lt;-》": "",
  1200. "\\(.pn. 平南\\)": "",
  1201. },
  1202. startFilter: function() {
  1203. clearInterval(unsafeWindow.show);
  1204. }
  1205. },
  1206. {siteName: "追书网",
  1207. url: "^https?://www\\.zhuishu\\.net/files/article/html/.*\\.html",
  1208. titleReg: /(?:正文 )?(.*) (\S+) \S+ - .*/,
  1209. titlePos: 1,
  1210. indexSelector: ".pagebottom>a:contains('目录')",
  1211. nextSelector: ".pagebottom>a:contains('下一页')",
  1212. prevSelector: ".pagebottom>a:contains('上一页')",
  1213. fixImage: true,
  1214. contentSelector: "#content",
  1215. contentReplace: {
  1216. "([^/])www\\.ZhuisHu\\.net": "$1",
  1217. },
  1218. contentPatch: function(fakeStub){
  1219. fakeStub.find("#content > .title, #content > .pagebottom").appendTo(fakeStub.find("body"));
  1220.  
  1221. fakeStub.find("#content").find("center, b:contains('最快更新')").remove();
  1222. }
  1223. },
  1224. {siteName: "猪猪岛小说",
  1225. url: "^https?://www\\.zhuzhudao\\.(?:com|cc)/txt/",
  1226. titleReg: "(.*?)最新章节-(.*?)-",
  1227. contentReplace: /[“"”]?猪猪岛小说.*|<\/?a[^>]+>|w+\.zhuZhuDao\.com|看更新最快的.*/ig
  1228. },
  1229. {siteName: "逸名文学屋",
  1230. url: "^https?://(bbs\\.vyming|www\\.9imw)\\.com/novel-read-\\d+-\\d+\\.html",
  1231. contentSelector: "#showcontent",
  1232. bookTitleSelector: ".headinfo a:first",
  1233. contentRemove: "p:contains(精品推荐:), p:contains(,免费小说阅读基地!), a",
  1234. contentReplace: [
  1235. "逸名文学屋:"
  1236. ]
  1237. },
  1238. {siteName: "奇书屋",
  1239. url: "^https?://www.qishuwu.com/\\w+/\\d+/",
  1240. titleReg: "(.*)_(.*)_.*_奇书屋",
  1241. },
  1242. {siteName: "17k小说网",
  1243. url: /^https?:\/\/\S+\.17k\.com\/chapter\/\S+\/\d+\.html$/,
  1244. titleReg: /(.*?)-(.*?)-.*/,
  1245. contentSelector: "#chapterContent",
  1246. contentRemove: ".chapter_update_time, h1, .qrcode, #authorSpenk, .like_box, #hotRecommend, .ct0416, .recent_read, #miniVoteBox",
  1247. contentReplace: [
  1248. '本书首发来自17K小说网,第一时间看正版内容!'
  1249. ],
  1250. contentPatchAsync: function($doc, callback) {
  1251. if (unsafeWindow.console.clear) {
  1252. unsafeWindow.console.clear = null;
  1253. }
  1254.  
  1255. function waitFor(condition, callback, timeout, timeoutFn) {timeout = timeout || 30 * 1000;timeoutFn = timeoutFn || function() {};var startTime = Date.now();var timeId = setInterval(function() { if (condition()) { callback(); clearInterval(timeId); } else if ((Date.now() - startTime) > timeout) { timeoutFn(); clearInterval(timeId); }}, 500);}
  1256.  
  1257. var Q = unsafeWindow.Q;
  1258.  
  1259. // 计算上一章节下一章节
  1260. function calPages() {
  1261. var json = Q.bookBigData.json;
  1262. var bookId = Q.bookid;
  1263.  
  1264. for (var i=0, c; c = json.list[i]; i++) {
  1265. if (c == Q.chapterid) {
  1266. var prevChapter = (0 === i ? null : json.list[i - 1]);
  1267. var nextChapter = (i + 1 < json.list.length ? json.list[i + 1] : null);
  1268.  
  1269. if (nextChapter) {
  1270. var nextUrl = '/chapter/' + bookId + '/' + nextChapter + '.html';
  1271. $doc.find('a:contains(下一章)')
  1272. .attr('href', nextUrl);
  1273.  
  1274. Q.chapterid = nextChapter;
  1275. }
  1276. if (prevChapter) {
  1277. var prevUrl = '/chapter/' + bookId + '/' + prevChapter + '.html';
  1278. $doc.find('a:contains(上一章)')
  1279. .attr('href', prevUrl);
  1280. }
  1281.  
  1282. break;
  1283. }
  1284. }
  1285. }
  1286.  
  1287. if (!Q.bookBigData.json) {
  1288. waitFor(function() {
  1289. return !!Q.bookBigData.json;
  1290. }, function() {
  1291. calPages();
  1292. callback();
  1293. });
  1294. } else {
  1295. calPages();
  1296. callback();
  1297. }
  1298. }
  1299. },
  1300. {siteName: "看下文学",
  1301. url: "^https?://www\\.kanxia\\.net/k/\\d*/\\d+/\\d+\\.html$",
  1302. titleReg: /(.*?)-(.*)TXT下载_看下文学/,
  1303. contentReplace: /看下文学/g
  1304. },
  1305. {siteName: "青帝文学网",
  1306. url: /^https?:\/\/www\.qingdi\.com\/files\/article\/html\/\d+\/\d+\/\d+\.html$/,
  1307. titleReg: /(.*?)最新章节_(.*?)_青帝文学网_.*/
  1308. },
  1309. {siteName: "侠客中文网",
  1310. url: /^https?:\/\/www\.xkzw\.org\/\w+\/\d+\.html/,
  1311. contentSelector: ".readmain_inner .cont",
  1312. contentPatch: function(fakeStub){
  1313. fakeStub.find('title').html(fakeStub.find('.readmain_inner h2').text());
  1314. }
  1315. },
  1316. {siteName: "ChinaUnix.net",
  1317. url: /^https?:\/\/bbs\.chinaunix\.net\/thread-.*\.html/,
  1318. contentSelector: ".t_f:first"
  1319. },
  1320. {siteName: "123du 小说",
  1321. url: /^https?:\/\/www\.123du\.(?:net|cc)\//,
  1322. titleReg: "(.*)-(.*) 百家乐",
  1323. titlePos: 1,
  1324. contentSelector: "#content, #contents",
  1325. contentReplace: "一秒记住.www.*|小说最新更新,来123读书www.123du.net",
  1326. contentRemove: "a",
  1327. contentPatch: function(fakeStub){
  1328. var content = fakeStub.find("#DivContentBG").html().match(/第\d*页([\s\S]*)一秒记住/)[1];
  1329. $('<div id="content"/>').html(content).appendTo(fakeStub.find('body'));
  1330. }
  1331. },
  1332. {siteName: "动力中文",
  1333. url: "^https?://dlzw\\.cc/article.*\\.html",
  1334. nextSelector: "span:contains('下一篇') > a",
  1335. prevSelector: "span:contains('上一篇') > a",
  1336. indexSelector: "#pt a[href^='http']"
  1337. },
  1338. {siteName: "塔读文学",
  1339. url: "^https?://www\\.tadu\\.com/book/\\d+/\\d+/",
  1340. bookTitleSelector: '.book-name_ a:first',
  1341. nDelay: 2000, // 延迟2秒加载下一页
  1342. contentSelector: "#partContent",
  1343. contentPatch: function(fakeStub){
  1344. var m = fakeStub.find("body").html().match(/\.html\(unescape\("(.*)"\)/);
  1345. if(m){
  1346. var unescapeContent = m[1];
  1347. fakeStub.find("#partContent").html(unescape(unescapeContent));
  1348. }
  1349. }
  1350. },
  1351. {siteName: "第一中文",
  1352. url: "^https?://www\\.dyzww\\.com/cn/\\d+/\\d+/\\d+\\.html$" ,
  1353. contentReplace: {
  1354. '<img.*?ait="(.*?)".*?>': "$1",
  1355. 'www\\.dyzww\\.com.*|♂|шШщ.*': ""
  1356. }
  1357. },
  1358. {siteName: "来书屋",
  1359. url: "^https?://www.laishuwu.com/html/\\d+/\\d+/\\d+.html",
  1360. titleSelector: ".chaptertitle h2",
  1361. bookTitleSelector: ".chaptertitle h1",
  1362. contentReplace: "txt\\d+/",
  1363. },
  1364. {siteName: "万书吧",
  1365. url: "^https?://www\\.wanshuba\\.com/Html/\\d+/\\d+/\\d+\\.html",
  1366. titleReg: "(.*?),(.*?)-万书吧",
  1367. titlePos: 1,
  1368. contentSelector: ".yd_text2",
  1369. contentReplace: [
  1370. "\\[www.*?\\]",
  1371. "\\(&nbsp;&nbsp;\\)",
  1372. "提供无弹窗全文字在线阅读,更新速度更快文章质量更好,如果您觉得不错就多多分享本站!谢谢各位读者的支持!",
  1373. "高速首发.*?,本章节是.*?地址为如果你觉的本章节还不错的话请不要忘记向您qq群和微博里的朋友推荐哦!"
  1374. ]
  1375. },
  1376. {siteName: "大文学",
  1377. url: "^https?://www\\.dawenxue\\.net/html/\\d+/\\d+/\\d+\\.html",
  1378. titleReg: "(.*?)-(.*)-大文学",
  1379. contentSelector: "#clickeye_content",
  1380. contentReplace: "\\(?大文学\\s*www\\.dawenxue\\.net\\)?|\\(\\)",
  1381. },
  1382. {siteName: "奇热",
  1383. url: "^https?://www\\.qirexs\\.com/read-\\d+-chapter-\\d+\\.html",
  1384. titleReg: "(.*?)-(.*?)-",
  1385. titlePos: 1,
  1386. contentSelector: "div.page-content .note",
  1387. contentRemove: "a",
  1388. contentReplace: "”奇热小说小说“更新最快|首发,/.奇热小说网阅读网!|奇热小说网提供.*|\\(手机用户请直接访问.*"
  1389. },
  1390. {siteName: "热点",
  1391. url: "^https?://www\\.hotsk\\.com/Html/Book/\\d+/\\d+/\\d+\\.shtml",
  1392. titleReg: "(.*?) 正文 (.*?)- 热点书库 -",
  1393. contentReplace: "\\(热点书库首发:www.hotsk.com\\)|www.zhuZhuDao.com .猪猪岛小说."
  1394. },
  1395. {siteName: "落秋中文",
  1396. url: "^https?://www\\.luoqiu\\.(com|net)/html/\\d+/\\d+/\\d+\\.html",
  1397. titleReg: "(.*?)-(.*?)-",
  1398. contentReplace: "&lt;/p&gt;"
  1399. },
  1400. {siteName: "全本小说网",
  1401. url: "^https?://www\\.qb5\\.com/xiaoshuo/\\d+/\\d+/\\d+\\.html",
  1402. titleReg: "(.*)_(.*)_",
  1403. contentRemove: "div[class]",
  1404. contentReplace: "全.{0,2}本.{0,2}小.{0,2}说.{0,2}网.{0,2}|[wWw ]+.{1,10}[CccǒOmMМ ]+",
  1405. },
  1406. {siteName: "手牵手小说网",
  1407. url: "^https?://www\\.sqsxs\\.com/.*\\d+/\\d+/\\d+\\.html",
  1408. bookTitleSelector: '#sitebar a:last',
  1409. contentReplace: [
  1410. "◆免费◆",
  1411. "★百度搜索,免费阅读万本★|访问下载txt小说.百度搜.|免费电子书下载|\\(百度搜\\)|『文學吧x吧.』|¤本站网址:¤",
  1412. "[☆★◆〓『【◎◇].*?(?:yunlaige|云 来 阁|yunlaige|免费看).*?[☆◆★〓』】◎◇]",
  1413. "【手机小说阅读&nbsp;m.】",
  1414. "BAIDU_CLB_fillSlot.*",
  1415. "&nbsp;关闭</p>",
  1416. "&nbsp;&nbsp;&nbsp;&nbsp;\\?",
  1417. "\\[☆更.新.最.快☆无.弹.窗☆全.免.费\\]",
  1418. '\\(.*?平南文学网\\)',
  1419. '{首发}|【首发】',
  1420. '=长=风',
  1421. '-优-优-小-说-更-新-最-快-\\.',
  1422. '发现一家非常好吃的手工曲奇店铺,可搜索淘宝.*',
  1423. '强烈推荐一家手工曲奇店,在淘宝搜索.*',
  1424. { "。\\.": "。" },
  1425. ]
  1426. },
  1427. {siteName: "六月中文网,盗梦人小说网",
  1428. url: "^https?://www\\.(?:6yzw\\.org|6yzw\\.com|daomengren\\.com)/.*\\.html",
  1429. bookTitleSelector: ".con_top>a:last",
  1430. contentRemove: "a[href]",
  1431. contentReplace: [
  1432. "纯文字在线阅读本站域名 520xs.Com 手机同步阅读请访问 M.520xs.Com",
  1433. "{飘天文学[\\s\\S]*您的支持就是我们最大的动力}",
  1434. "((未完待续),|精彩推荐:,)?最新最快更新热门小说,享受无弹窗阅读就在:",
  1435. "一秒记住【】,本站为您提供热门小说免费阅读。",
  1436. "百度搜索 本书名.*",
  1437. "欢迎您的光临,任何搜索引擎搜索.*给大家带来的不便深感抱歉!!",
  1438. "\\(?&nbsp;&nbsp; ?提供』。如果您喜欢这部作品,欢迎您来创世中文网[\\s\\S]+",
  1439. "[\\((]未完待续.{1,2}本文字由.*",
  1440. "//添加开头|会员特权抢先体验",
  1441. "更新最快|更新快纯文字|看最新章节|六月中文网|78小说|h﹒c﹒d|穿越小说吧 sj131|\\*五月中文网5.c om\\*",
  1442. "\\d楼[\\d\\-: ]+(?:&nbsp;)+ \\|(?:&nbsp;)+|吧主\\d+(?:&nbsp;)+|支持威武,嘎嘎!",
  1443. "www,|&nbsp;\\\\|“梦”(&nbsp;| )*“小”(&nbsp;| )*(“说” )?“网”|“岛”(&nbsp;| )+“说”",
  1444. /(百度搜索 )?本书名 \+ 盗梦人 看最快更新/ig,
  1445. "520xs.com ”520小说“小说章节更新最快",
  1446. "看最新最全小说|最快更新,(?:无弹窗)?阅读请。",
  1447. "纯文字在线阅读本站域名  手机同步阅读请访问",
  1448. "本文由 …… 首发",
  1449. "(首发)|【首发】",
  1450. "&amp;nbsp",
  1451. ]
  1452. },
  1453. {siteName: "飞卢小说网",
  1454. url: "^https?://b\\.faloo\\.com/p/\\d+/\\d+\\.html",
  1455. titleSelector: "#title h1",
  1456. bookTitleSelector: "div.nav > a:last",
  1457. bookTitleReplace: '小说$',
  1458.  
  1459. nextSelector: "a#next_page",
  1460. prevSelector: "a#pre_page",
  1461. indexSelector: "a#huimulu",
  1462.  
  1463. contentSelector: "#main > .main0",
  1464. contentRemove: "> *:not(#con_imginfo, #content), .p_content_bottom",
  1465. contentReplace: [
  1466. "飞卢小说网 b.faloo.com 欢迎广大书友光临阅读,最新、最快、最火的连载作品尽在飞卢小说网!",
  1467. ],
  1468. contentPatch: function(fakeStub){
  1469. fakeStub.find("#content").find(".p_gonggao").remove();
  1470. // fakeStub.find("#con_imginfo").prependTo("#content");
  1471. }
  1472. },
  1473. {siteName: "顶点小说",
  1474. url: "^https?://www\\.(?:23us|x23us|23wx|xs222)\\.(?:com|cc)/html/\\d+/\\d+/\\d+\\.html$",
  1475. bookTitleSelector: '.crumbs > div > a:last, #amain > dl > dt > a:last',
  1476. indexSelector: "#footlink a:contains('返回目录')",
  1477. prevSelector: "#footlink a:contains('上一页')",
  1478. nextSelector: "#footlink a:contains('下一页')",
  1479. contentSelector: "#contents",
  1480. contentReplace: [
  1481. "\\(看小说到顶点小说网.*\\)|\\(\\)|【记住本站只需一秒钟.*】",
  1482. '一秒记住【.*读及下载。',
  1483. 'www.xstxt.org',
  1484. 'wenxuemi.com',
  1485. '23us.com',
  1486. '顶点小说 X23US.com更新最快',
  1487. 'www.23us.cc更新最快',
  1488. '免费小说门户',
  1489. '\\|顶\\|点\\|小\\|說\\|網更新最快',
  1490. '\\\\\\|顶\\\\\\|点\\\\\\|小\\\\\\|说\\\\\\|2\\|3\\|u\\|s\\|.\\|c\\|c\\|',
  1491. ],
  1492. contentPatch: function(fakeStub){
  1493. var temp=fakeStub.find('title').text();
  1494. var realtitle = temp.replace(/第.*卷\s/,'');
  1495. fakeStub.find('title').html(realtitle);
  1496. }
  1497. },
  1498. {siteName: '23中文',
  1499. url: '^https?://www\\.23zw\\.(com|me)/.*\\.html',
  1500. contentSelector: '#chapter_content',
  1501. contentRemove: 'h1',
  1502. contentReplace: [
  1503. '的朋友,你可以即可第一时间找到本站哦。',
  1504. '手机看小说哪家强\\?手机阅读网',
  1505. ',最快更新.*?最新章节!',
  1506. '看.*?最新章节到长风文学',
  1507. '本文由首发',
  1508. '章节更新最快',
  1509. '顶点小说.23us.。',
  1510. '\\(顶点小说\\)',
  1511. '看最新最全',
  1512. 'R1152',
  1513. '\\.n√et',
  1514. '中文网',
  1515. '更新最快',
  1516. ]
  1517. },
  1518. {siteName: '笔下阁',
  1519. url: "^https?://www\\.bixiage\\.com/\\w+/\\d+/\\d+/\\d+\\.html",
  1520. titleReg: "(.*)最新章节免费在线阅读_(.*)_笔下阁",
  1521. indexSelector: ".read_tools a:contains('返回目录')",
  1522. prevSelector: ".read_tools a:contains('上一页')",
  1523. nextSelector: ".read_tools a:contains('下一页')",
  1524. contentReplace: [
  1525. "本书最新免费章节请访问|请记住本站的网址|请使用访问本站",
  1526. "看更新最快的.*www.bixiage.com",
  1527. "笔下阁为您提供全文字小说.*",
  1528. "如果你觉得笔下阁不错.*",
  1529. "本篇是小说.*章节内容,如果你发现内容错误.*"
  1530. ]
  1531. },
  1532. {siteName: '双德小说网',
  1533. url: "^https?://www\\.shuangde\\.cc/.*\\.html",
  1534. bookTitleSelector: '.title > h2 > a',
  1535. contentRemove: '.title, div[align="center"]',
  1536. },
  1537. {siteName: '爱尚小说网',
  1538. url: '^https?://www.a240.com/read/\\d+/\\d+.html',
  1539. titleReg: '(.*) - (.*?) - 爱尚小说网',
  1540. titlePos: 1,
  1541. contentRemove: '.bottem, center',
  1542. contentReplace: '<!--章节内容开始-->'
  1543. },
  1544. {siteName: 'E度文学网',
  1545. url: '^https?://www.173ed.com/read/\\d+/\\d+.html',
  1546. contentRemove: 'a[href*="173e"]',
  1547. contentReplace: [
  1548. '全文字小说W.*?\\.com',
  1549. 'E度文学网更新最快',
  1550. 'www\\.♀173ed.com♀'
  1551. ]
  1552. },
  1553. {siteName: "3Z中文网",
  1554. url: "^https?://www\\.zzzcn\\.com\\/(3z\\d+/\\d+\\/|modules\\/article\\/App\\.php\\?aid=\\d+&cid=\\d+){1}$",
  1555. // titleReg: "(.*?)-(.*)TXT下载",
  1556. contentSelector: "#content3zcn",
  1557. indexSelector: "a:contains('返回目录')",
  1558. prevSelector: "a:contains('上 一 页')",
  1559. nextSelector: "a:contains('下 一 页'), a:contains('返回书架')",
  1560. contentReplace: [
  1561. /[{(][a-z\/.]+(?:首发文字|更新超快)[})]/ig,
  1562. "手机小说站点(wap.zzzcn.com)",
  1563. "一秒记住.*为您提供精彩小说阅读。",
  1564. ],
  1565. contentPatch: function(fakeStub){
  1566. fakeStub.find("a:contains('返回书架')").html("下 一 页").attr("href", fakeStub.find("a:contains('返回目录')").attr("href"));
  1567. fakeStub.find("#content3zcn").find(".titlePos, font.tips, a").remove();
  1568. }
  1569. },
  1570. {siteName: "比奇中文网",
  1571. url: "^https?://www\\.biqi\\.me/files/article/html/\\d+/\\d+/\\d+\\.html",
  1572. titleSelector: "#lbChapterName",
  1573. bookTitleSelector: "#TOPNAV td:first > a:last",
  1574. contentReplace: [
  1575. "http://www.biqi.me比奇中文网永久网址,请牢记!",
  1576. "www.biqi.me比奇中文网一直在为提高阅读体验而努力,喜欢请与好友分享!",
  1577. "[{【]比奇中文网首发www.biqi.me[}】]",
  1578. ]
  1579. },
  1580. {siteName: "书哈哈小说网",
  1581. url: "^https?://(?:read|www)\\.shuhaha\\.com/Html/Book/\\d+/\\d+/\\d+\\.html",
  1582. titleSelector: "#htmltimu",
  1583. bookTitleSelector: [".srcbox > a:nth-child(2)", /目录$/],
  1584. contentSelector: "#BookText",
  1585. contentRemove: 'a[href*="www.shuhaha.com"]',
  1586. contentReplace: [
  1587. '‘‘', '’’',
  1588. '(\\.shuh&amp;n)',
  1589. /<p[^>]*>(&nbsp;){4}网<\/p>/gi
  1590. ]
  1591. },
  1592. {siteName: "SF 轻小说",
  1593. url: '^https?://book.sfacg.com/Novel/\\d+/\\d+/\\d+/',
  1594. titleReg: '(.*?)-(.*?)-.*',
  1595. contentSelector: '#ChapterBody',
  1596. },
  1597. {siteName: "武林中文网",
  1598. url: '^https?://www\\.50zw\\.(com|co|la)/book_\\d+/\\d+\\.html',
  1599. bookTitleSelector: '.srcbox > a:last',
  1600. contentReplace: [
  1601. '更新最快【】',
  1602. '&lt;/dd&gt;',
  1603. '&lt;center&gt; &lt;fon color=red&gt;',
  1604. '一秒记住【武林中文网.*',
  1605. '武林中文网 www.*',
  1606. ]
  1607. },
  1608. {siteName: "乡村小说网",
  1609. url: '^https?://www\\.xiangcunxiaoshuo\\.com/shu/\\d+/\\d+\\.html',
  1610. // bookTitleSelector: '.read_m > .list',
  1611. titleReg: '(.*?)_(.*?)_.*_.*',
  1612. contentSelector: '.yd_text2',
  1613. contentReplace: [
  1614. '[wWw]+.23uS.(?:coM|com)',
  1615. '乡&amp;村&amp;.*?\\.co[mM]',
  1616. ]
  1617. },
  1618. {siteName: "杂书网",
  1619. url: "^https?://www\\.zashu\\.net/books/\\d+/\\d+/\\d+\\.html",
  1620. contentReplace: [
  1621. "吋煜牝咱.*?杂书网(?:杠杠的)?",
  1622. "吋煜牝咱看书神器",
  1623. "(?:吋煜牝咱|飝现洅咱|茇阺畱匝).*?[Cc]om",
  1624. "吋煜牝咱",
  1625. "飝现洅咱", "殢萾嘎匝",
  1626. "看小说“杂书网zashu.net”",
  1627. "手机站:m.zashu.net 电脑站:www.zashu.net",
  1628. ]
  1629. },
  1630. {siteName: "小说巴士",
  1631. url: "^https?://www\\.xs84\\.com/\\d+_\\d+/",
  1632. bookTitleSelector: ".con_top a:last",
  1633. contentReplace: [
  1634. "§推荐一个无广告的小说站.*? §",
  1635. "☆本站最快更新.*?☆",
  1636. "纯文字在线阅读.*?</br>",
  1637. "www.X S 8 4.com",
  1638. "《》 www.obr />",
  1639. "。。 w.2.obr",
  1640. "\\[w w w.x s.*?.c o m 小说.*?\\]",
  1641. "╂上.*?╂",
  1642. "\\*\\*顶\\*\\*点.{0,3}小说",
  1643. "___小.说.巴.士 www.xS84.com___",
  1644. ],
  1645. contentPatch: function() {
  1646. $('<script>')
  1647. .text('clearInterval(show);')
  1648. .appendTo('body')
  1649. .remove();
  1650. }
  1651. },
  1652. {siteName: "123言情",
  1653. url: '^https?://www\\.123yq\\.(com|org)/read/\\d+/\\d+/\\d+\\.shtml',
  1654. bookTitleSelector: '.con_top > a:last',
  1655. contentSelector: "#TXT",
  1656. contentRemove: '.bottem, .red, .contads, a',
  1657. },
  1658. {siteName: "热门小说网",
  1659. url: '^https?://www.remenxs.com/du_\\d+/\\d+/',
  1660. bookTitleSelector: 'section.readhead > div.read_t > div.lf > a:nth-child(2)',
  1661. nextSelector: '.pagego > font:contains("下一章") + a',
  1662. prevSelector: '.pagego > font:contains("上一章") + a',
  1663. contentSelector: ".yd_text2",
  1664. contentRemove: '.adrs, .con_w, a',
  1665. contentReplace: [
  1666. '您可以在百度里搜索“.*',
  1667. '为了方便下次阅读,你可以点击下方的.*'
  1668. ]
  1669. },
  1670.  
  1671. // === 内容补丁
  1672. {siteName: "给力文学小说阅读网",
  1673. url: "^https?://www\\.geiliwx\\.com/.*\\.shtml",
  1674. titleReg: "-?(.*)_(.*)最新章节_给力",
  1675. titlePos: 1,
  1676. contentRemove: 'h1, font[color], center',
  1677. contentReplace: [
  1678. "网站升级完毕!感谢对给力文学网的支持!",
  1679. "(百度搜索给力文学网更新最快最稳定\\)",
  1680. "【sogou,360,soso搜免费下载小说】",
  1681. "\\[乐\\]\\[读\\]小说.23.[Cc]m",
  1682. "给力文学网",
  1683. "看最快更新",
  1684. "小说网不跳字",
  1685. "\\.com",
  1686. "BAIDU_CLB_fillSlot\\(.*",
  1687. "--小-说-www-23wx-com",
  1688. "&nbsp;&nbsp;,请",
  1689. '\\.www\\.GEILIWX开心阅读每一天',
  1690. ],
  1691. contentPatch: function(d) {
  1692. if (!d.find('#content').length) {
  1693. var html = d.find('body').html();
  1694. var content = html.match(/<!--go-->([\s\S]*?)<!--over-->/i)[1];
  1695.  
  1696. content = $('<div id="content">').html(content);
  1697. if (content.find('#adright').size()) {
  1698. content = content.find('#adright');
  1699. }
  1700. content.appendTo(d.find('body'));
  1701. }
  1702. }
  1703. },
  1704.  
  1705. // ================== 采用 iframe 方式获取的 ====================
  1706. {siteName: "16K小说网",
  1707. url: "^https?://www\\.16kbook\\.org/Html/Book/\\d+/\\d+/\\d+\\.shtml$",
  1708. titleReg: '(\\S+) (.*)- 16K小说网',
  1709. useiframe: true,
  1710. contentRemove: '.bdlikebutton',
  1711. contentReplace: {
  1712. '(<center>)?<?img src..(http://www.16kbook.org)?(/tu/\\S+\\.jpg).(>| alt."\\d+_\\d+_\\d*\\.jpg" />)(</center>)?': "$3",
  1713. "/tu/shijie.jpg":"世界", "/tu/xiangdao.jpg":"想到", "/tu/danshi.jpg":"但是", "/tu/huilai.jpg":"回来", "/tu/yijing.jpg":"已经", "/tu/zhende.jpg":"真的", "/tu/liliang.jpg":"力量", "/tu/le.jpg":"了", "/tu/da.jpg":"大", "/tu/shengli.jpg":"胜利", "/tu/xiwang.jpg":"希望", "/tu/wandan.jpg":"完蛋", "/tu/de.jpg":"的",
  1714. "16kbook\\s*(首发更新|小说网)": "",
  1715. }
  1716. },
  1717. {siteName: "读读看",
  1718. url: "^https?://www\\.dudukan\\.net/html/.*\\.html$",
  1719. contentReplace: "看小说“就爱读书”|binhuo|www\\.92to\\.com",
  1720. useiframe: true,
  1721. mutationSelector: "#main",
  1722. mutationChildCount: 0,
  1723. },
  1724. {siteName: "读零零(有问题,只显示一半内容)",
  1725. url: "https?://www\\.du00\\.(?:com|cc)/read/\\d+/\\d+/[\\d_]+\\.html",
  1726. titleReg: "(.*?)(?:第\\d+段)?,(.*) - 读零零小说网",
  1727. titlePos: 1,
  1728. // prevSelector: "#footlink a:first",
  1729. // indexSelector: "#footlink a:contains('目录')",
  1730. // nextSelector: "#footlink a:last",
  1731. // 内容
  1732. contentSelector: "#pagecontent, .divimage",
  1733. // useiframe: true,
  1734. // mutationSelector: "#pagecontent",
  1735. // mutationChildCount: 2,
  1736. contentRemove: "font",
  1737. contentReplace: [
  1738. "读零零小说网欢迎您的光临.*?txt格式下载服务",
  1739. ",好看的小说:|本书最新免费章节请访问。",
  1740. "\\*文學馆\\*",
  1741. "\\(未完待续请搜索,小说更好更新更快!",
  1742. "www\\.DU00\\.com",
  1743. ],
  1744. checkSection: true
  1745. },
  1746. {siteName: "78小说网",
  1747. url: "^https?://www\\.78xs\\.com/article/\\d+/\\d+/\\d+.shtml$",
  1748. contentHandle: false,
  1749. titleReg: "(.*?) (?:正文 )?(.*) 78小说网",
  1750. indexSelector: "a:contains('目 录')",
  1751. prevSelector: "a:contains('上一章')",
  1752. nextSelector: "a:contains('下一章')",
  1753. contentSelector: "#content",
  1754. useiframe: true,
  1755. contentReplace: [
  1756. "//.*?78xs.*?//",
  1757. "\\(全文字小说更新最快\\)",
  1758. ],
  1759. contentPatch: function(fakeStub){
  1760. fakeStub.find('p.title').empty(); // 去掉内容中带的章节标题
  1761. }
  1762. },
  1763. {siteName: "151看书网",
  1764. url: "^https?://www\\.151kan\\.com/kan/.*\\.html",
  1765. contentSelector: "#msg",
  1766. useiframe: true,
  1767. mutationSelector: "#msg",
  1768. contentReplace: [
  1769. /[\/|]?www\.151(?:看|kan)\.com[\/|]?/ig,
  1770. /151看书网(?:纯文字)?/ig,
  1771. ]
  1772. },
  1773. {siteName: "就爱读书",
  1774. url: "^https?://www\\.92to\\.com/\\w+/\\w+/\\d+\\.html$",
  1775. titleReg: "(.*?)-(.*?)-",
  1776. useiframe: true,
  1777. timeout: 500,
  1778. contentReplace: "看小说.就爱.*"
  1779. },
  1780. {siteName: "书书网",
  1781. url: "^https?://www\\.shushuw\\.cn/shu/\\d+/\\d+\\.html",
  1782. titleReg: "(.*) (.*?) 书书网",
  1783. titlePos: 1,
  1784. useiframe: true,
  1785. timeout: 500,
  1786. contentReplace: "!~![\\s\\S]*"
  1787. },
  1788. {siteName: "找小说网",
  1789. url: "^https?://www\\.zhaoxiaoshuo\\.com/chapter-\\d+-\\d+-\\w+/",
  1790. titleReg: "(.*) - (.*) - 找小说网",
  1791. titlePos: 1,
  1792. useiframe: true,
  1793. timeout: 500,
  1794. contentRemove: "div[style]"
  1795. },
  1796. {siteName: "ABC小说网",
  1797. url: "^https?://www\\.bookabc\\.net/.*\\.html",
  1798. useiframe: true
  1799. },
  1800.  
  1801. // ============== 内容需要2次获取的 =========================
  1802. {siteName: "手打吧",
  1803. url: /^https?:\/\/shouda8\.com\/\w+\/\d+\.html/,
  1804. contentReplace: /[w\s\[\/\\\(]*.shouda8.com.*|(\/\/)?[全文字]?首发|手打吧|www.shou.*|\(w\/w\/w.shouda8.c\/o\/m 手、打。吧更新超快\)|小说 阅读网 www.xiaoshuoyd .com/ig,
  1805. contentPatch: function(fakeStub){
  1806. var scriptSrc = fakeStub.find('body').html().match(/outputContent\('(.*txt)'\)/)[1];
  1807. scriptSrc = "http://shouda8.com/ajax.php?f=http://shouda8.com/read" + scriptSrc;
  1808. fakeStub.find('#content').attr({
  1809. "class": 'reader-ajax',
  1810. src: scriptSrc
  1811. });
  1812. }
  1813. },
  1814. {siteName: "哈哈文学",
  1815. url: /^https?:\/\/www\.hahawx\.com\/.*htm/,
  1816. titleReg: /(.*?)-(.*?)-.*/,
  1817. contentSelector: "#chapter_content",
  1818. contentReplace: /(?:好书推荐|书友在看|其他书友正在看|好看的小说|推荐阅读):。|(?:www|www|book).*(?:com|net|org|com|net)|全文字阅读|无弹窗广告小说网|哈哈文学\(www.hahawx.com\)|souDU.org|Soudu.org|jīng彩推荐:/ig,
  1819. contentPatch: function(fakeStub){
  1820. var $content = fakeStub.find("#chapter_content");
  1821. var m = $content.find("script").text().match(/output\((\d+), "(\d+\.txt)"\);/);
  1822. if(m && m.length == 3){
  1823. var aid = m[1],
  1824. files = m[2];
  1825. var subDir = "/" + (Math.floor(aid / 1000) + 1),
  1826. subDir2 = "/" + (aid - Math.floor(aid / 1000) * 1000);
  1827. $content.attr({
  1828. class: "reader-ajax",
  1829. src: "http://r.xsjob.net/novel" + subDir + subDir2 + "/" + files,
  1830. charset: "gbk"
  1831. });
  1832. }
  1833. }
  1834. },
  1835. {siteName: "天天中文",
  1836. url: "^https?://www\\.ttzw\\.com/book/\\d+/\\d+\\.html",
  1837. titleSelector: "#chapter_title",
  1838. bookTitleSelector: ".fl.pl20 a:last",
  1839. contentSelector: "#text_area",
  1840. contentReplace: /www.ttzw.com|www.c66c.com|手机用户请到阅读。|<p>\s*a<\/p>/ig,
  1841. contentPatch: function(fakeStub) {
  1842. var m = fakeStub.find('#text_area script').text().match(/outputTxt\("(.*)"\);/);
  1843. if (m) {
  1844. fakeStub.find('#text_area').attr({
  1845. class: "reader-ajax",
  1846. src: unsafeWindow.getServer() + m[1],
  1847. charset: "gbk"
  1848. });
  1849. }
  1850. }
  1851. },
  1852.  
  1853. // ===========================================================
  1854. {siteName: "好看小說網",
  1855. url: "^https?://tw\\.xiaoshuokan\\.com/haokan/\\d+/\\d+\\.html",
  1856. contentSelector: ".bookcontent",
  1857. prevSelector: "a.redbutt:contains('上一頁')",
  1858. indexSelector: "a.redbutt:contains('返回章節目錄')",
  1859. nextSelector: "a.redbutt:contains('下一頁')",
  1860. contentReplace: "[a-z;&]*w.[xx]iaoshuokan.com 好看小說網[a-z;&族】)]*"
  1861. },
  1862. {siteName: "E品中文网",
  1863. url: "^https?://www\\.epzww\\.com/book/\\d+/\\d+",
  1864. titleReg: "(.*?),(.*?),",
  1865. contentSelector: "#showcontent",
  1866. },
  1867. {siteName: "飘天文学",
  1868. url: "^https?://www\\.piaotian\\.(net|com)/html/\\d+/\\d+/\\d+\\.html",
  1869. // titleReg: "(.*)最新章节,(.*),飘天文学",
  1870. bookTitleSelector: '#content > h1 > a',
  1871. contentSelector: "#content",
  1872. useiframe: true, // 否则 content 在 body 下面
  1873. contentRemove: "h1, table, .toplink",
  1874. contentReplace: [
  1875. /[{〖]请在百度搜索.*[}〗]|.(?:百度搜索飄天|无弹窗小说网).*\.Net.|\[飄天.*无弹窗小说网\]/ig,
  1876. '\\{飘天文学www.piaotian.net感谢各位书友的支持,您的支持就是我们最大的动力\\}',
  1877. '章节更新最快',
  1878. '支持网站发展,逛淘宝买东西.*',
  1879. '天才壹秒記住,為您提供精彩閱讀。.*'
  1880. ],
  1881. },
  1882. {siteName: "天使小说网",
  1883. url: "^https?://www\\.tsxs\\.cc/files/article/html/\\d+/\\d+/\\d+\\.html",
  1884. contentSelector: "#content"
  1885. },
  1886. {siteName: "紫雨阁小说网",
  1887. url: "^https?://www\\.ziyuge\\.com/\\w+/\\w+/\\d+/\\d+/\\d+\\.html",
  1888. titleReg: "(.*?)-正文-(.*?)-紫雨阁小说网",
  1889. contentSelector: ".reader_content",
  1890. nextSelector: "#divNext a",
  1891. prevSelector: "#divPrev a",
  1892. contentReplace: "\\(.*www.ziyuge.com.*\\)"
  1893. },
  1894. {siteName: "破风中文网",
  1895. url: "^https?://www\\.pofeng\\.net/xiaoshuo/\\d+/\\d+\\.html",
  1896. useiframe: true
  1897. },
  1898. {siteName: "读客吧",
  1899. url: "^https?://dukeba\\.com/book/\\d+/\\d+/\\d+\\.shtml",
  1900. useiframe: true,
  1901. contentSelector: "#content > div[style]",
  1902. contentRemove: "a, div[align]:has(font)",
  1903. },
  1904. {siteName: "一起阅",
  1905. url: "^https?://www\\.17yue\\.com/\\w+/\\d+/\\d+\\.html",
  1906. useiframe: true,
  1907. },
  1908. {siteName: "诺秋网",
  1909. url: "^https?://www\\.nuoqiu\\.com/static/\\d+/\\d+\\.html",
  1910. titleReg: "(.*) (.*) 诺秋网",
  1911. titlePos: 1,
  1912. useiframe: true,
  1913. contentReplace: "┏━━━━━━━━━━━━━━━━━━━━━━━━━┓[\\s\\S]+诺秋网文字更新最快……】@!!"
  1914. },
  1915. {siteName: "言情后花园",
  1916. url: "^https?://www\\.yqhhy\\.cc/\\d+/\\d+/\\d+\\.html",
  1917. titleReg: "(.*)-(.*)-.*-言情后花园",
  1918. titlePos: 1,
  1919. contentSelector: "#content",
  1920. contentRemove: "a, span[style], script",
  1921. contentReplace: "请记住本站: www.yqhhy.cc|更多,尽在言情后花园。"
  1922. },
  1923. {siteName: "六九中文",
  1924. url: "^https?://www.(?:69zw|kan7).com/\\w+/\\d+/\\d+/\\d+.html",
  1925. titleSelector: ".chapter_title",
  1926. bookTitleSelector: ".readhead h1",
  1927. contentSelector: ".yd_text2",
  1928. // titleReg: "(.*)?_(.*)-六九中文",
  1929. contentReplace: [
  1930. "[\\*]+本章节来源六九中文.*请到六九中文阅读最新章节[\\*]+|-\\\\[wW]+.*书友上传/-",
  1931. "\\\\请到 www.69zw.com 六\\*九.*?/",
  1932. "【 注册会员可获私人书架,看书更方便!:】",
  1933. "首发<br />",
  1934. ]
  1935. },
  1936. {siteName: "免费小说阅读网",
  1937. titleReg: "(.*) , (.*) , 免费小说阅读网",
  1938. titlePos: 1,
  1939. url: "^https?://book\\.yayacms\\.com/\\w+/book_\\d+_\\d+.html",
  1940. contentRemove: "a, div[style]",
  1941. contentReplace: "http://book.YaYaCMS.com/.*|book.yayacms.com",
  1942. },
  1943. {siteName: "书农在线书库",
  1944. url: "^https?://www\\.shunong\\.com/yuedu/\\d+/\\d+/\\d+.html",
  1945. contentSelector: ".bookcontent",
  1946. },
  1947. {siteName: "努努书坊",
  1948. url: "^https?://(?:book\\.kanunu\\.org|www\\.kanunu8\\.com)/.*/\\d+\\.html",
  1949. titleReg: /(.*) - (.*) - 小说在线阅读 - .* - 努努书坊/,
  1950. titlePos: 1,
  1951. contentSelector: "table:eq(4) p",
  1952. indexSelector: "a[href^='./']",
  1953. },
  1954. {siteName: "五月中文网",
  1955. url: "^https?://5ycn\\.com/\\d+/\\d+/\\d+\\.html",
  1956. contentRemove: "div[align='center'], a",
  1957. },
  1958. {siteName: "笔下中文",
  1959. url: "^https?://www\\.bxzw\\.org/\\w+/\\d+/\\d+/\\d+\\.shtml",
  1960. contentRemove: "div[align='center'], center, #footlink1",
  1961. contentReplace: "www\\.bxzw\\.org|//无弹窗更新快//|\\(看精品小说请上.*\\)|\\(看.*最新更新章节.*\\)"
  1962. },
  1963. {siteName: "着笔中文网",
  1964. url: "^https?://.*zbzw\\.com/\\w+/\\d+\\.html",
  1965. contentReplace: "精彩小说尽在.*"
  1966. },
  1967. {siteName: "D586小说网",
  1968. url: '^https?://www\\.d586\\.com/',
  1969. contentSelector: ".yd_text2",
  1970. contentRemove: 'a',
  1971. contentReplace: [
  1972. '【www.13800100.com文字首发D586小说网】',
  1973. '【☆D586小说网☆//文字首发】.*'
  1974. ]
  1975. },
  1976. {siteName: "豌豆文学网",
  1977. url: "^https?://www.wandoou.com/book/\\d+/\\d+\\.html",
  1978. titleReg: '(.*?)最新章节-(.*)-.*无弹窗广告_豌豆文学网',
  1979. contentRemove: "center",
  1980. contentReplace: [
  1981. /[{(]<a href.*[})]|网欢迎广大书友光临阅读,.*/ig,
  1982. /[レ★]+.*(?:请支持)?豌(?:.|&amp;)?豆.?文.?学.*[レ★]+/ig,
  1983. /[((【]豌.?豆.?文.?学.*[))】]/ig,
  1984. /∷更新快∷∷纯文字∷|http:永久网址,请牢记!/ig,
  1985. /(?:{|\\|\/|\()*豌.?豆.?文.?学.?网.*?(?:高速更新|\\\/|})+/ig,
  1986. /更新最快最稳定|看小说“”/ig,
  1987. /&lt;strng&gt;.*?&lt;\/strng&gt;/ig,
  1988. /\(凤舞文学网\)|\( *\)|「启航文字」|79阅.读.网/ig,
  1989. /高速首发.*?本章节是.*/ig,
  1990. /百度搜索自从知道用百度搜索,妈妈再也不用担心我追不到最快更新了/ig,
  1991. ]
  1992. },
  1993. {siteName: "都来读小说网",
  1994. url: /^https?:\/\/www\.doulaidu\.com\/[^\/]+\/\d+\/\d+\.html/,
  1995. useiframe: true,
  1996. contentReplace: [
  1997. /www..+.(?:com|net)/ig,
  1998. /都来读小说网首发|www\.[a-z0-9]+\.(?:org|com)/ig,
  1999. ]
  2000. },
  2001. {siteName: "小说TXT",
  2002. url: /^https?:\/\/www\.xshuotxt\.com\//,
  2003. contentReplace: "\\(.*无弹窗全文阅读\\)",
  2004. contentPatch: function(fakeStub) {
  2005. fakeStub.find('#title a').remove();
  2006. }
  2007. },
  2008. {siteName: "疯狂中文网",
  2009. url: "^https?://www\\.fkzww\\.com/",
  2010. contentRemove: ".bottem, a[href='http://www.fkzww.com']",
  2011. contentReplace: [
  2012. /收藏【.*?疯狂中文网\)/ig,
  2013. ]
  2014. },
  2015. {siteName: "吾读小说网",
  2016. url: "^https?://www\\.5du5\\.com/book/.*\\.html",
  2017. contentReplace: '\\(吾读小说网 <a.*无弹窗全文阅读\\)'
  2018. },
  2019. {siteName: "UU看书",
  2020. url: "^https?://www\\.uukanshu\\.(?:com|net)/.*/\\d+/\\d+.html",
  2021. contentReplace: [
  2022. /* 替换以下
  2023. UU看书 www.uukanshu.net
  2024. 'UU看书 www.uukanshu.net '
  2025. 'UU看书 www.uukanshu.net'
  2026. 'UU看书 www.uukanshu.net'
  2027. 'UU看书 www.uukanshu.net '
  2028. 'UU看书www.uukanshu.net '
  2029. 'UU看书 www.uukanshu.net'
  2030. 'UU看书 www.uukanshu.net'
  2031. 'UU看书 www.uukanshu.net '
  2032. 'UU看书 www.uukanshu.net '
  2033. ‘UU看书 www.uukanshu.net ’
  2034. ‘UU看书 www.uukanshu.net ’
  2035. ‘UU看书 www.uukanshu.net ’
  2036. UU看书 www.uukanshu.net
  2037. */
  2038. /[UuUu]+看书\s*www.[UuUu]+[kk][aa][nn][ss][hh][UuUu].[nn][ee][tt]/g,
  2039. '[UU]*看书[(\\(].*?[)\\)]文字首发。',
  2040. '请记住本书首发域名:。笔趣阁手机版阅读网址:',
  2041. '\\(\\)',
  2042. ]
  2043. },
  2044. {siteName: "长风文学网",
  2045. url: "^https?://www\\.cfwx\\.net/files/article/html/\\d+/\\d+/\\d+\\.html",
  2046. titleSelector: '.title',
  2047. bookTitleSelector: '.linkleft > a:last',
  2048. contentReplace: [
  2049. '([^\\u4E00-\\u9FFF]+)长\\1风\\1文\\1学[^\\n]+t',
  2050. ]
  2051. },
  2052. {siteName: "云来阁",
  2053. url: "^https?://www\\.yunlaige\\.com/html/\\d+/\\d+/\\d+\\.html",
  2054. titleSelector: '.ctitle',
  2055. bookTitleSelector: '#hlBookName',
  2056. contentSelector: '#content',
  2057. contentRemove: '.bottomlink, a, .cad, .footer, .adbottom',
  2058. contentReplace: [
  2059. '[☆★◆〓『【◎◇].*?(?:yunlaige|云 来 阁|yunlaige).*?[☆◆★〓』】◎◇]',
  2060. '《更新最快小说网站:雲来阁http://WWW.YunLaiGe.COM》',
  2061. '【當你閱讀到此章節,請您移步到雲來閣閱讀最新章節,或者,雲來閣】',
  2062. '【看恐怖小说、玄幻小说、请大家登陆黑岩居http://www.heiyanju.com万本小说免费看】',
  2063. '【本书作者推荐:(?:百度搜索)?云来閣,免费观看本书最快的VIP章节】',
  2064. '搜索引擎搜索关键词\\s*云.来.阁,各种小说任你观看,破防盗章节',
  2065. '搜索关键词 云.来.阁,各种小说任你观看,破防盗章节',
  2066. '◢百度搜索雲来阁,最新最快的小说更新◣',
  2067. '\\(云来阁小说文学网www.yunlaige.com\\)',
  2068. '如您已阅读到此章节,请移步到.*',
  2069. '《想看本书最新章节的书友们,百度搜索一下.*',
  2070. '===百!?度搜索.*?新章节===',
  2071. '【最新更新】',
  2072. '值得您收藏。。',
  2073. '小说“小说章节',
  2074. '纯文字在线阅读本站域名',
  2075. '手机同步阅读请访问',
  2076. '±顶±点±小±说,ww',
  2077. '■dingddian小说,ww∨23w→■m',
  2078. 'w∨23w',
  2079. 'www23wxcom',
  2080. '¥℉頂¥℉点¥℉小¥℉',
  2081. '£∝頂£∝点£∝小£∝',
  2082. '篮。色。书。巴,',
  2083. '<!--\\?[\\(<]', // 提取内容后出现的注释标志,造成后面的内容没了
  2084. '看书&nbsp;&nbsp; 要?',
  2085. '喜欢网就上。',
  2086. '无弹窗小说,.*',
  2087. '本书最快更新网站请:.*',
  2088. 'V<!--\\?',
  2089. ]
  2090. },
  2091. {siteName: "乐文小说网",
  2092. url: /^https?:\/\/(www|m)\.lwxs520\.com\/books\/\d+\/\d+\/\d+.html/,
  2093. siteExample: 'http://www.lwxs520.com/books/2/2329/473426.html',
  2094. bookTitleSelector: 'h2',
  2095. chapterTitleReplace: 'WwW.lwxs520.Com|乐文小说网',
  2096.  
  2097. contentRemove: '#content>:not(p)',
  2098. contentReplace: [
  2099. '看小说到乐文小说网www.lwxs520.com',
  2100. '喜欢乐文小说网就上www.*(?:COM|com)',
  2101. '爱玩爱看就来乐文小说网.*',
  2102. '\\(LWXS520。\\)',
  2103. 'M.LWxS520.com&nbsp;乐文移动网',
  2104. /乐文小说网值得.+/g,
  2105. '乐\\+文\\+小说&nbsp;Www.しwXs520.Com',
  2106. '乐文\s*小说 www.lwxs520.com',
  2107. '&乐&文&小说 \\{www\\}.\\{lw\\}\\{xs520\\}.\\{com\\}',
  2108. '<乐-文>小说www.しWXS520.com',
  2109. '-乐-文-小-说-www-lwxs520-com',
  2110. '?乐?文?小说 wwW.lWXs520. COM',
  2111. ';乐;文;小说 www.lw+xs520.com',
  2112. '小说&nbsp;wWw.Lwxs520.cOm',
  2113. 'www.LWXS520.com',
  2114. 'www.lwxs520.com 首发哦亲',
  2115. '[wWw]+.[lし]w[xχX][sS]520.[cc][ooO][mM]',
  2116. 'lwxs520.com\\|?',
  2117. '[しlL][ωWw][χXXx][ssS]520',
  2118. /\(未完待续.+/g,
  2119. '\\P?[樂乐]\\P文\\P小\\P?说',
  2120. '》乐>文》小说',
  2121. '乐+文+小说',
  2122. '《乐<文《小说',
  2123. '樂文小說',
  2124. ':乐:文:小说',
  2125. '`乐`文`小说`',
  2126. '=乐=文=小说',
  2127. '@樂@文@小@说|',
  2128. ';乐;文;小说',
  2129. '︾樂︾文︾小︾说\\|',
  2130. '`乐`文`小说`',
  2131. '@乐@文@小说',
  2132. 'lw+xs520',
  2133. '♂!',
  2134. '3w.',
  2135. '\\(\\)',
  2136. ]
  2137. },
  2138. {siteName: '我爱小说',
  2139. url: '^https?://www\\.woaixiaoshuo\\.com/xiaoshuo/\\d+/\\d+/\\d+\\.html',
  2140. bookTitleSelector: '#lbox > b',
  2141. contentSelector: '#readbox',
  2142. contentRemove: '#papgbutton, #content',
  2143. },
  2144. {siteName: "米花在线书库",
  2145. url: /book\.mihua\.net\/\w+\/\d+\/\d+\/.+\.html/,
  2146. titleSelector: "#title",
  2147. contentSelector: "#viewbook"
  2148. },
  2149. {siteName: "58小说网",
  2150. url: /^https?:\/\/(www|book)\.(58)?58xs\.com\/html\/\d+\/\d+\/\d+\.html/,
  2151. titleSelector: "h1",
  2152. indexSelector: "#footlink > a:eq(1)",
  2153. prevSelector: "#footlink > a:eq(0)",
  2154. nextSelector: "#footlink > a:eq(2)",
  2155. contentSelector: "#content",
  2156. contentRemove: ".f1, .c1"
  2157. },
  2158. {siteName: "天天美文网",
  2159. url: /www\.365essay\.com\/\w+\/.+.htm/,
  2160. titleSelector: ".title > h1",
  2161. contentSelector: "#zoomc td",
  2162. contentRemove: ".page-bottomc"
  2163. },
  2164. {siteName: "天涯武库",
  2165. url: /wx\.ty2016\.com\/.+\.html$/,
  2166. bookTitleSelector: "td[width='800'][height='25']>a[href='./']",
  2167. titleSelector: "strong>font",
  2168. indexSelector: "td a[href='./']",
  2169. nextSelector: "td[width='28%'] a",
  2170.  
  2171. contentSelector: "td[width='760'] p",
  2172. contentHandle: false,
  2173. },
  2174. {siteName: "黄金屋中文网",
  2175. url: /www\.hjwzw\.com\/Book\/Read\/\d+[,_]\d+$/,
  2176. titleSelector: "h1",
  2177. indexSelector: "td a[href='./']",
  2178. contentSelector: "#AllySite+div",
  2179. contentRemove: "b, b+p",
  2180. contentReplace: [
  2181. "请记住本站域名:"
  2182. ]
  2183. },
  2184. {siteName: "梦远书城",
  2185. url: /www\.my285\.com(?:\/\w+){3,5}\/\d+\.htm$/,
  2186. useiframe: true,
  2187. contentSelector: "table:eq(2) tr:eq(3)",
  2188. },
  2189. {siteName: "更新吧",
  2190. url: "^https?://www\\.gengxin8\\.com/read/\\d+/\\d+.html$",
  2191. bookTitleSelector: '.left a:last',
  2192. contentSelector: "#chaptertxt",
  2193. useiframe: true,
  2194. },
  2195. {siteName: "乐文小说网",
  2196. url: "^https?://www\\.365xs\\.org/books/\\d+/\\d+/\\d+\\.html",
  2197. titleSelector: ".kfyd h1",
  2198. bookTitleSelector: "ul.bread-crumbs a:last",
  2199. contentSelector: "#content",
  2200. // contentReplace: []
  2201. },
  2202. {siteName: "舞若小说网",
  2203. url: "^https?://www\\.wuruo\\.com/files/article/html/\\d+/\\d+/\\d+\\.html",
  2204. bookTitleSelector: ".text a:eq(1)",
  2205. contentSelector: "#zhengwen",
  2206. contentReplace: [
  2207. '【更多精彩小说请访问www.wuruo.com】',
  2208. '(www.wuruo.com舞若小说网首发)',
  2209. '【舞若小说网首发】',
  2210. ]
  2211. },
  2212. {siteName: "大书包小说网",
  2213. url: "^https?://www\\.dashubao\\.com?/book/\\d+/\\d+/\\d+\\.html",
  2214. bookTitleSelector: ".read_t > .lf > a:nth-child(3)",
  2215. contentSelector: ".yd_text2",
  2216. contentReplace: [
  2217. ]
  2218. },
  2219. {siteName: "爬书网",
  2220. url: "^https?://www\\.pashuw\\.com/BookReader/\\d+-\\d+/\\d+\\.html",
  2221. bookTitleSelector: "#paihangbang_select > a:last()",
  2222. nextSelector: "#next2 a",
  2223. prevSelector: "#prev2 a",
  2224. indexSelector: "#fhml2 a",
  2225. contentRemove: '.novel_bot',
  2226. },
  2227. {siteName: "闪文书库",
  2228. url: "^https?://read\\.shanwen\\.com/html/\\d+/\\d+/\\d+\\.html",
  2229. titleSelector: '.newstitle',
  2230. contentRemove: '#titlebottom',
  2231. contentReplace: [
  2232. '闪文网址中的.*?注册会员</a>'
  2233. ]
  2234. },
  2235. {siteName: "品书网",
  2236. url: "^https?://www\\.vodtw\\.com/Html/Book/\\d+/\\d+/\\d+\\.html",
  2237. bookTitleSelector: '.srcbox > a:last()',
  2238. contentRemove: 'a',
  2239. contentReplace: [
  2240. '品书网 www.voDtw.com◇↓',
  2241. '品书网 www.vodtW.com',
  2242. '品 书 网 (w W W . V o Dtw . c o M)',
  2243. '复制网址访问\\s*http://[%\\d\\w]+'
  2244. ]
  2245. },
  2246. {siteName: "凤凰小说网",
  2247. url: "^https?://www\\.fhxs\\.com/read/\\d+/\\d+/\\d+\\.shtml",
  2248. bookTitleSelector: '.con_top > a:last()',
  2249. contentRemove: '.bottem',
  2250. contentReplace: [
  2251. ]
  2252. },
  2253. {siteName: "小说巴士",
  2254. url: "^https?://www\\.xsbashi\\.com/\\d+_\\d+/",
  2255. contentReplace: [
  2256. '全文阅读如您已阅读到此章[節节].*?,,,,',
  2257. '看小说首发推荐去眼快看书',
  2258. '最快更新,阅读请。___小/说/巴/士 Www.XSBASHI.coM___',
  2259. '___小/说/巴/士 www.XSBASHI.com___',
  2260. 'lala如您已阅读到此章節,請移步到.*?速记方法:,\\]',
  2261. 'lala如您已阅读到此章節.*?敬請記住我們新的網址筆-趣-閣',
  2262. '起舞电子书访问:. 。',
  2263. '≧哈,m\\.',
  2264. '\\[\\s*超多好看\\]',
  2265. '热门【首发】',
  2266. '===百度搜索.*?===',
  2267. '===\\*\\*小说巴士.*?===',
  2268. ]
  2269. },
  2270. {siteName: "思兔阅读",
  2271. url: "^https?://\\w+\\.sto\\.cc/book-\\d+-\\d+.html",
  2272. titleReg: "(.*?)_(.*?)_全文在線閱讀_思兔",
  2273. titlePos: 0,
  2274. //bookTitleSelector: "h1",
  2275. prevSelector: "a:contains('上壹頁'), a:contains('上壹页')",
  2276. nextSelector: "a:contains('下壹頁'), a:contains('下壹页')",
  2277. contentSelector: "div#BookContent",
  2278. contentRemove: 'span',
  2279. },
  2280. {siteName: "去读读",
  2281. url: "^https?://www\\.qududu\\.net/book/\\d+/\\d+/\\d+\\.html",
  2282. contentSelector: "#kui-page-read-txt",
  2283. },
  2284. {siteName: "33言情",
  2285. url: "^https?://www\\.33yq\\.com/read/\\d+/\\d+/\\d+\\.shtml",
  2286. contentRemove: 'a, .bottem, .red',
  2287. },
  2288. {siteName: "巫师图书馆.",
  2289. url: "^https?://www\\.54tushu\\.com/book_library/chaptershow/theId/\\d+\\.html",
  2290. bookTitleSelector: "#m-book-title",
  2291. titleSelector: "div.title",
  2292. prevSelector: "div.pageInfo a:first",
  2293. nextSelector: "div.pageInfo a:last",
  2294. indexSelector: "a[title='返回书页']",
  2295. useiframe: true,
  2296. timeout: 1000,
  2297. contentSelector: "div#ChapterContent",
  2298. contentPatch: function(fakeStub){
  2299. var bookTitle = fakeStub.find('meta[name="keywords"]').attr('content');
  2300. fakeStub.find('body').append('<div id="m-book-title">' + bookTitle + '</div>');
  2301. }
  2302. },
  2303.  
  2304. // ===== 特殊的获取下一页链接
  2305. {siteName: "看书啦",
  2306. url: "^https?://www.kanshu.la/book/\\w+/\\d+\\.shtml",
  2307. titleReg: "(.*)-(.*)-看书啦",
  2308. titlePos: 1,
  2309. nextUrl: function($doc){
  2310. var html = $doc.find('script:contains(next_page = ")').html();
  2311. var m = html.match(/next_page = "(.*?)";/);
  2312. if (m) return m[1];
  2313. },
  2314. prevUrl: function($doc){
  2315. var html = $doc.find('script:contains(preview_page = ")').html();
  2316. var m = html.match(/preview_page = "(.*?)";/);
  2317. if (m) return m[1];
  2318. }
  2319. },
  2320. {siteName: "书阁网",
  2321. url: "^https?://www\\.bookgew\\.com/Html/Book/\\d+/\\d+/\\d+\\.htm",
  2322. titleReg: "(.*)-(.*?)-书阁网",
  2323. titlePos: 1,
  2324. // titleSelector: ".newstitle",
  2325. nextUrl: function($doc){
  2326. var html = $doc.find('script:contains(nextpage=)').html();
  2327. var m = html.match(/nextpage="(.*?)";/);
  2328. if (m) return m[1];
  2329. },
  2330. prevUrl: function($doc) {
  2331. var html = $doc.find('script:contains(prevpage=)').html();
  2332. var m = html.match(/prevpage="(.*?)";/);
  2333. if (m) return m[1];
  2334. }
  2335. },
  2336.  
  2337. // {siteName: "雅文言情小说吧", // 一章分段
  2338. // url: "^https?://www\\.yawen8\\.com/\\w+/\\d+/\\d+\\.html",
  2339. // contentSelector: "#content .txtc"
  2340. // }
  2341.  
  2342. {siteName:'妙笔阁',
  2343. url: /^https?:\/\/www\.miaobige\.com\/.*\.html|^https?:\/\/www.(?:52dsm|banfusheng).com\/chapter\/\d+\/\d+.html/i,
  2344. siteExample:'http://www.miaobige.com/book/5_1586/1006320.html',
  2345. // 有的会提示防采集章节
  2346. fInit: function () {
  2347. $('<script>')
  2348. .text('$(document).unbind("contextmenu selectstart")')
  2349. .appendTo(document.body);
  2350. },
  2351.  
  2352. useiframe: true,
  2353. mutationSelector: '#content',
  2354. mutationChildCount: 1,
  2355. startLaunch: function($doc){
  2356. var $content = $doc.find('#content');
  2357.  
  2358. if ($content.text().match(/妙笔阁防盗模式:|小说阅读模式:/)) {
  2359. // 清空不完全的内容节点,通过 mutationSelector 等待内容 完全加载
  2360. $content.html('');
  2361. }
  2362. },
  2363. contentReplace: '妙笔阁,无弹窗,更新快,记住www.miaobige.com',
  2364. // contentPatch: function($doc){
  2365. // var $content = $doc.find('#content');
  2366. // var txt = $content.text();
  2367.  
  2368. // if (0 === txt.trim().indexOf('防采集章节,')) {
  2369. // var mNewLink = $content.html().match(/http:\/\/www\.miaobige\.com\/book\/(\d)_(\d+)\/(\d+)\.html/i);
  2370. // if (mNewLink) {
  2371. // $content .addClass(READER_AJAX)
  2372. // .attr({
  2373. // src: '/js/ajaxtxt.asp',
  2374. // charset: 'gbk'
  2375. // })
  2376. // .data('post', {
  2377. // sid: mNewLink[2],
  2378. // zid: mNewLink[3],
  2379. // cid: mNewLink[1]
  2380. // })
  2381. // .text('请等待加载…');
  2382. // }
  2383. // }
  2384. // },
  2385. // http://www.miaobige.com/read/11180/5216676.html 章节内容缺失(下面方式过于复杂,无效)
  2386. // contentPatchAsync: function($doc, callback) {
  2387. // var $content = $doc.find('#content');
  2388. // var txt = $content.text();
  2389.  
  2390. // if (txt.indexOf('妙笔阁防盗模式:') > -1) {
  2391. // // 很复杂。一串看不懂的 js 生成 $.post('/ajax/content/',{sid:11180,zid:15662893,cid:3},function(data){$('#content').html(data);});
  2392. // var $script = $doc.find('script:contains(H=~[])');
  2393. // if (!$script.length) {
  2394. // console.error('查找 script 失败');
  2395. // return
  2396. // }
  2397.  
  2398. // // 临时劫持
  2399. // var $ = {
  2400. // post: function(url, data, mCallback) {
  2401. // console.log('222222')
  2402. // $content.addClass(READER_AJAX)
  2403. // .attr({
  2404. // src: url,
  2405. // charset: 'UTF-8'
  2406. // })
  2407. // .data('post', data)
  2408. // .text('请等待加载…');
  2409.  
  2410. // callback()
  2411. // }
  2412. // };
  2413.  
  2414. // console.log('will eval script')
  2415. // debugger
  2416. // eval($script.text());
  2417.  
  2418. // // var funcStr = ''
  2419. // // var scriptFn = $script.text().trim().replace(/\(\);$/, '');
  2420. // // eval('funcStr = ' + scriptFn + '.toString()')
  2421. // } else {
  2422. // callback()
  2423. // }
  2424. // }
  2425. },
  2426.  
  2427. {siteName: '书海小说',
  2428. url: '^https?://www\\.shuhai\\.com/read/\\d+/\\d+\\.html',
  2429. bookTitleSelector: '.path2 a:nth-of-type(3)',
  2430. titleSelector: '.read_top h1',
  2431. prevSelector: '.read .read_dwn p a:nth-of-type(1)',
  2432. indexSelector: '.read .read_dwn p a:nth-of-type(2)',
  2433. nextSelector: '.read .read_dwn p a:nth-of-type(3)',
  2434. contentSelector: '.read .txt',
  2435. },
  2436. {siteName: "欢乐书客",
  2437. url: "^https?://www\\.hbooker\\.com/chapter/book_chapter_detail/\\d+",
  2438. bookTitleSelector: ".breakcrumb > a:last",
  2439. titleSelector: ".book-read-box .read-hd h3",
  2440. useiframe: true,
  2441. timeout: 500,
  2442. contentSelector: ".book-read-box .read-bd",
  2443. contentRemove: ".book-read-box .barrage, #J_BtnGuide, .book-read-box .read-bd i.num, .chapter i, .J_Num, .num, .book-read-box .read-hd p:nth-of-type(1) span",
  2444.  
  2445. indexSelector: ".book-read-page a.btn-list",
  2446. nextUrl: function ($doc){
  2447. return $doc.find('#J_BtnPageNext').attr('data-href');
  2448. },
  2449. prevUrl: function ($doc){
  2450. return $doc.find('#J_BtnPagePrev').attr('data-href');
  2451. },
  2452. },
  2453. {siteName: '棉花糖小说网',
  2454. url: '^https?://www\\.mht\\.la/\\d+/\\d+/\\d+\\.html',
  2455. bookTitleSelector: '.nav > a:nth-of-type(3)',
  2456. titleSelector: '.read_title h1',
  2457. prevSelector: '.pagego a:nth-of-type(1)',
  2458. indexSelector: '.pagego a:nth-of-type(2)',
  2459. nextSelector: '.pagego a:nth-of-type(3)',
  2460. contentSelector: '.content',
  2461. contentRemove: 'a, .contads',
  2462. contentReplace: [
  2463. '下载本书最新的txt电子书请点击:',
  2464. '本书手机阅读:',
  2465. '发表书评:',
  2466. '为了方便下次阅读,你可以在点击下方的.*谢谢您的支持!!',
  2467. '手机用户可访问wap.mianhuatang.la观看小说,跟官网同步更新.*',
  2468. ],
  2469. },
  2470. {siteName: '墨缘文学网',
  2471. url: '^https?://www\\.moyuanwenxue\\.com/xiaoshuo/\\d+/\\d+/\\d+\\.htm',
  2472. contentSelector: '#chapterContent',
  2473. contentReplace: [
  2474. {"ZHAN":"战"},
  2475. {"LU":"路"},
  2476. {"SHOU  QIANG":"手枪"},
  2477. {"si wang":"死亡"},
  2478. ],
  2479. },
  2480. // 必须先用键盘箭头翻页后变成 article\reader 的url后才不会有断章现象
  2481. {siteName: "格格党",
  2482. url: 'http://www\\.ggdown\\.com/modules/article/reader\\.php\\?aid=.*',
  2483. siteExample: 'http://www.ggdown.com/modules/article/reader.php?aid=41490&cid=13833393',
  2484. indexSelector: '.link.xb a:contains("返回列表")',
  2485. contentSelector: "#BookText",
  2486. contentReplace: [
  2487. '记住我们的网址噢。百度搜;格!!格!!党.或者直接输域名/g/g/d/o/w/n/./c/o/m',
  2488. ]
  2489. },
  2490. {siteName: "233言情",
  2491. url: 'http://233yq\\.com/xiaoshuo/.*/.*\\.html',
  2492. siteExample: 'http://233yq.com/xiaoshuo/UsRA_mfLLcU/cwsM8t2ibWE.html',
  2493. titleSelector: '.bname h1',
  2494. bookTitleSelector: '.b21 h3:first()',
  2495. contentSelector: ".cn",
  2496. contentRemove: '.bottem',
  2497. },
  2498. {siteName: "笔趣阁",
  2499. url: /^https?:\/\/www\.biquge\.com\.tw\/\d+_\d+\/\d+.html/,
  2500. siteExample: 'http://www.biquge.com.tw/17_17768/8280656.html',
  2501. contentSelector: "#content"
  2502. },
  2503. {siteName: "笔趣看",
  2504. url: /^https?:\/\/www\.biqukan\.com\/\d+_\d+\/\d+.html/,
  2505. bookTitleSelector: '.path .p > a:last',
  2506. contentReplace: [
  2507. 'http://www.biqukan.com/.*',
  2508. '请记住本书首发域名:www.biqukan.com.*',
  2509. ]
  2510. },
  2511. {siteName: '大主宰小说网',
  2512. url: 'www\\.daizhuzai\\.com/\\d+/\\d+\\.html',
  2513. bookTitleSelector: '.readbox article .info span:nth-of-type(1) a',
  2514. titleSelector: '.readbox article .title h1 a',
  2515. prevSelector: '.readbox .operate li:nth-of-type(1) a',
  2516. indexSelector: '.readbox .operate li:nth-of-type(2) a',
  2517. nextSelector: '.readbox .operate li:nth-of-type(3) a',
  2518. useiframe: true,
  2519. mutationSelector: "#chaptercontent",
  2520. mutationChildCount: 2,
  2521. timeout: 500,
  2522. contentSelector: '.readbox article .content',
  2523. contentRemove: '',
  2524. contentReplace: [
  2525. { '。&': '。' },
  2526. '△番茄小說○網☆',
  2527. '☆ 番茄○△小說網',
  2528. '番茄小說網☆',
  2529. ],
  2530. },
  2531. {siteName: "墨缘文学网",
  2532. url: "^http://www\\.mywenxue\\.com/xiaoshuo/\\d+/\\d+/\\d+\\.htm",
  2533. bookTitleSelector: '#htmltimu h1 a',
  2534. titleSelector: "#htmltimu h2 span",
  2535. prevSelector: ".papgbutton a:nth-of-type(1)",
  2536. indexSelector: ".papgbutton a:nth-of-type(2)",
  2537. nextSelector: ".papgbutton a:nth-of-type(3)",
  2538. useiframe: true,
  2539. contentSelector: '.contentbox > .contentbox',
  2540. contentRemove: "strong, a",
  2541. contentReplace: [
  2542. { 'ZHAN': '战' },
  2543. { 'SI': '思' },
  2544. { 'si wang': '死亡' },
  2545. { 'DING': '订' },
  2546. { 'SHI ': '式' },
  2547. { 'LU': '路' },
  2548. { 'jin ru': '进入' },
  2549. { 'bao zha': '爆炸' },
  2550. { 'DAO': '刀' },
  2551. { 'Dan': '弹' },
  2552. { 'Ke': '客' },
  2553. { 'GOU': '购' },
  2554. { 'kuo san': '扩散' },
  2555. { 'Bu': '步' },
  2556. { 'SHOU  QIANG': '手枪' },
  2557. '更多请登录墨缘文学网.*欢迎您的来访 >>>',
  2558. '更多请登录墨缘文学网.*欢迎您的来访\\[ .* \\]',
  2559. '\\( http.*墨缘文学网 \\)',
  2560. ],
  2561. },
  2562. {siteName: '大海中文',
  2563. url: 'http://www\\.dhzw\\.org/book/\\d+/\\d+/\\d+\\.html',
  2564. contentReplace: [
  2565. '恋上你看书网 630bookla.*',
  2566. '\\(\\)',
  2567. ]
  2568. },
  2569. {siteName: '爱上书屋',
  2570. url: 'https?://www.23sw.net/\\d+/\\d+/\\d+.html',
  2571. titleReg: /(.*?) (.*?),/,
  2572. contentReplace: [
  2573. '\\[www.23sw.net\\]',
  2574. ]
  2575. },
  2576. {siteName: '书轩网',
  2577. url: '^https?://www.bookxuan.com/\\d+_\\d+/\\d+.html',
  2578. bookTitleSelector: '.con_top a:last',
  2579. contentReplace: [
  2580. { '&amp;quot;': '"', },
  2581. 'getreadset;',
  2582. '&lt;div class="divimage"&gt;&lt;img src="',
  2583. ],
  2584. contentPatch: function($doc) {
  2585. $doc.find('#content[title="书,轩,网"]').remove();
  2586. }
  2587. },
  2588. {siteName: '大家读书院',
  2589. url: '^https?://www.dajiadu.net/files/article/html/\\d+/\\d+/\\d+.html',
  2590. contentSelector: '#content, #content1',
  2591. contentRemove: '.copy',
  2592. },
  2593. {siteName: '2k小说阅读网',
  2594. url: 'https?://www.2kxs.com/xiaoshuo/\\d+/\\d+/\\d+.html',
  2595. exampleUrl: 'http://www.2kxs.com/xiaoshuo/106/106185/23622820.html',
  2596. contentSelector: '.Text',
  2597. contentRemove: 'a, font, strong',
  2598. contentReplace: [
  2599. '2k小说阅读网',
  2600. ]
  2601. },
  2602. {siteName: "新笔趣阁",
  2603. url: "^http:\/\/www.biqu6.com\/[0-9_]+\/[0-9]+.html$",
  2604.  
  2605. titleReg: /(.*?)章节目录 [-_\\\/](.*?)[-_\/].*/,
  2606. titlePos: 0,
  2607. titleSelector: "#title h1",
  2608.  
  2609. indexSelector: "a:contains('章节目录')",
  2610. prevSelector: "a:contains('上一章')",
  2611. nextSelector: "a:contains('下一章')",
  2612.  
  2613. contentSelector: "#content",
  2614. contentReplace: [
  2615. /\*/g
  2616. ],
  2617. },
  2618. {siteName: "涅破小说网",
  2619. url: "^http://www.niepo.net/html/\\d+/\\d+/\\d+.html",
  2620. contentReplace: [
  2621. '.*最新章节.*http://www.niepo.net/.*'
  2622. ],
  2623. },
  2624. {siteName: '全本小说网',
  2625. url: 'http://www.ybdu.com/xiaoshuo/\\d+/\\d+/\\d+.html',
  2626. contentRemove: '.infos, .chapter_Turnpage',
  2627. },
  2628. {siteName: '连载书',
  2629. exampleUrl: 'http://www.lianzaishu.com/4_4017/2172985.html',
  2630. url: '^https?://www.lianzaishu.com/\\d+_\\d+/\\d+.html',
  2631. bookTitleSelector: '.read-top h2 a',
  2632. contentRemove: 'h1, h2, .textinfo, .adbox, .read-page',
  2633. contentReplace: [
  2634. '&lt;html&gt;', '&lt;/html&gt;',
  2635. '&lt;head&gt;&lt;/head&gt;',
  2636. '&lt;body&gt;', '&lt;/body&gt;',
  2637. '&lt;div&gt;',
  2638. ]
  2639. },
  2640. {siteName: "露西弗俱乐部",
  2641. exampleUrl: 'https://www.lucifer-club.com/chapter-83716-1.html',
  2642. url: /^https:\/\/www\.lucifer\-club\.com\/.*\.html/,
  2643. bookTitleSelector: "#luf_local > a:nth-child(3)",
  2644.  
  2645. indexSelector: '.luf_news_title > a:contains("目录")',
  2646.  
  2647. contentSelector: "#luf_news_contents",
  2648. contentHandle: false,
  2649. contentRemove: "> form, #luf_local, .luf_top_ad, .luf_news_title, .luf_page_control, .luf_comment",
  2650. contentReplace: [
  2651. '保护版权 尊重作者 @ 露西弗俱乐部 www.lucifer-club.com',
  2652. ],
  2653. },
  2654.  
  2655. // 这网站为了防抓取,内容顺序都是不对的,只好采用 iframe 方式
  2656. {siteName: '和图书',
  2657. exampleUrl: 'http://www.hetushu.com/book/1421/964983.html',
  2658. url: '^https?://www.hetushu.com/book/\\d+/\\d+.html',
  2659. bookTitleSelector: '#left h3',
  2660. nextSelector: 'a#next',
  2661. prevSelector: 'a#pre',
  2662. indexSelector: '#left h3 a',
  2663. useiframe: true,
  2664. // 后面的是 和图书 的干扰码
  2665. contentRemove: 'h2, acronym, bdo, big, cite, code, dfn, kbd, q, s, samp, strike, tt, u, var',
  2666. contentPatch: function($doc) {
  2667. // 转换 div 到 p
  2668. $doc.find('#content div').each(function() {
  2669. let html = $(this).html();
  2670. $(this).replaceWith(
  2671. $('<p>').html(html)
  2672. );
  2673. });
  2674. }
  2675. },
  2676.  
  2677. // 移动版
  2678. {siteName: "掌阅手机网",
  2679. url: "https?://wap\\.yc\\.ireader\\.com\\.cn/book/\\d+/\\d+/",
  2680. titleReg: "(.*?),.*?作品 - 掌阅小说网",
  2681. titlePos: 0,
  2682. titleSelector: "h4",
  2683. contentSelector: "div.text",
  2684. isVipChapter: function ($doc) {
  2685. if ($doc.find('.vipzj').length) {
  2686. return true;
  2687. }
  2688. }
  2689. },
  2690.  
  2691. ];
  2692.  
  2693. // ===== 小说拼音字、屏蔽字修复 =====
  2694. // 运行在未替换 <br> 之前,.* 可能会造成全部替换
  2695. const replace = {
  2696. // ===格式整理===
  2697. // "\\(|\\[|\\{|(|【|{":"(",
  2698. // "\\)|\\]|\\}|)|】|}":")",
  2699.  
  2700. // 需要?
  2701. ",": ",",
  2702. // ":": ":", "\\?":"?", // 会造成起点的图片无法替换
  2703.  
  2704. "\\*|*": "*",
  2705. "[wWwW]{3}": "www",
  2706. "w{3}(\u3001|\u3002)": "www.",
  2707. "[cCcC][oOoO][mMmM]": "com",
  2708. "[nNnN][eeEE][ttTT]": "net",
  2709. "[cCcC][nNnN]": "cn",
  2710. "(\\.|\u3001|\u3002)com": ".com",
  2711. "(\\.|\u3001|\u3002)net": ".net",
  2712. "(\\.|\u3001|\u3002)cn": ".cn",
  2713. "[pPpP][sSsS][::]": "ps:",
  2714. "。{5,7}": "……", "~{2,50}": "——", "…{3,40}": "……", "-{3,20}": "——",
  2715. //"。(,|,|。)": "。",
  2716. // "?(,|,)": "?",
  2717. //"”(,|,|。)": "”",
  2718. "@{3,}": "",
  2719.  
  2720. // === 段末的多余的r ===
  2721. "\\\\r<br>": "<br>",
  2722.  
  2723. // === 一些特殊的替换 ===
  2724. "\\[+CP.*(http://file.*\\.jpg)\\]+": "<img src='$1'>",
  2725. "『(.)』": "$1", // "『色』": "色",
  2726.  
  2727. // === 去广告 ===
  2728. "\\[搜索最新更新尽在[a-z\\.]+\\]": "",
  2729. "<a>手机用户请到m.qidian.com阅读。</a>": "",
  2730. ".{2,4}中文网欢迎广大书友": "",
  2731. "访问下载txt小说|◎雲來閣免费万本m.yunlaige.com◎": "",
  2732. "〖∷更新快∷无弹窗∷纯文字∷.*?〗": "",
  2733. '超快稳定更新小说[,,]': '', "本文由 。。 首发": "",
  2734. '”小说“小说章节更新最快': '',
  2735. '如果觉得好看,请把本站网址推荐给您的朋友吧!': '',
  2736. '本站手机网址:&nbsp;&nbsp;请互相通知向您QQ群【微博/微信】论坛贴吧推荐宣传介绍!': '',
  2737. "fqXSw\\.com": "", "\\.5du|\\.5du5\\.": "",
  2738. "\\[\\]": "",
  2739. "如果您觉得网不错就多多分享本站谢谢各位读者的支持": "",
  2740. "全文字无广告|\\(看书窝&nbsp;看书窝&nbsp;无弹窗全文阅读\\)": "",
  2741. "。。+[\\s ]*看最新最全小说": "",
  2742. "水印广告测试": "",
  2743. "\\(平南文学网\\)": "", "讀蕶蕶尐說網": "",
  2744. "比奇提示:如何快速搜自己要找的书籍": "", "《百度书名\\+比奇》即可快速直达": "",
  2745. "~无~错~小~说": "",
  2746.  
  2747. "\\(一秒记住小说界\\)|\\*一秒记住\\*": "",
  2748. "uutxt\\.org|3vbook\\.cn|www\\.qbwx\\.com|WWw\\.YaNkuai\\.com|www\\.btzw\\.com|www\\.23uS\\.com": "",
  2749. "txt53712/": "",
  2750. "\xa0{4,12}": "\xa0\xa0\xa0\xa0\xa0\xa0\xa0",
  2751.  
  2752. // === 通用去广告
  2753. "[wwW]{1,3}[.\\.]23uS[.\\.](?:coM|com)": "",
  2754.  
  2755. // === 星号屏蔽字还原 ===
  2756. // === 八九 ===
  2757. "十有(\\*{2})": "十有八九",
  2758. "十有bā'九": "十有八九",
  2759. "(\\*{2})不离十": "八九不离十",
  2760. "(\\*{2})点": "八九点",
  2761. "(\\*{2})个": "八九个",
  2762. "(\\*{2})岁": "八九岁",
  2763. "(\\*{2})成": "八九成",
  2764. "(\\*{2})年": "八九年",
  2765. "一八(\\*{2})": "一八八九",
  2766.  
  2767. // === SM ===
  2768. "G(\\*{2})": "GSM",
  2769.  
  2770. // === 情色 ===
  2771. "感(\\*{2})彩": "感情色彩",
  2772.  
  2773. // === 大法 ===
  2774. "强(\\*{2})u5B9D": "强大法宝",
  2775. "强(\\*{2})宝": "强大法宝",
  2776. "种魔(\\*{2})": "种魔大法",
  2777. "巨(\\*{2})": "巨大法",
  2778. "强(\\*{2})术": "强大法术",
  2779. "(\\*{2})师": "大法师",
  2780.  
  2781. // === 肉体 ===
  2782. "(\\*{2})凡胎": "肉体凡胎",
  2783. "夺取她的(\\*{2})": "夺取她的肉体",
  2784. "夺取他的(\\*{2})": "夺取他的肉体",
  2785. "(\\*{2})与精神": "肉体与精神",
  2786. "(\\*{2})素材": "肉体素材",
  2787. "(\\*{2})材料": "肉体材料",
  2788. "在(\\*{2})上": "在肉体上",
  2789.  
  2790. // === 赤裸 ===
  2791. "(\\*{4})着": "赤裸着",
  2792. "(\\*{2})裸": "赤裸裸",
  2793. "浑身(\\*{2})": "浑身赤裸",
  2794.  
  2795. // === 射 ===
  2796. "枪(\\*{4})": "枪发射",
  2797. "(\\*{4})而出": "喷射而出",
  2798. "光(\\*{2})": "光四射",
  2799.  
  2800. // === 鱼水 ===
  2801. "(\\*{2})之欢": "鱼水之欢",
  2802.  
  2803. // === 国军 ===
  2804. "(\\*{2})队": "国军队",
  2805. "(\\*{2})舰": "国军舰",
  2806. "(\\*{2})方": "国军方",
  2807.  
  2808. // === 露阴 ===
  2809. "暴(\\*{2})谋": "暴露阴谋",
  2810.  
  2811. // === 欲望 ===
  2812. "的(\\*{2})是无止境的": "的欲望是无止境的",
  2813. "邪恶的(\\*{2})": "邪恶的欲望",
  2814. "被(\\*{2})支配": "被欲望支配",
  2815. "掀桌的(\\*{2})": "掀桌的欲望",
  2816. "控制不住(\\*{2})": "控制不住欲望",
  2817. "求生的(\\*{2})": "求生的欲望",
  2818. "求生(\\*{2})": "求生欲望",
  2819. "购买(\\*{2})": "购买欲望",
  2820. "永无止境的(\\*{2})": "永无止境的欲望",
  2821. "(\\*{2})的发泄": "欲望的发泄",
  2822. "发泄(\\*{2})": "发泄欲望",
  2823. "杀戮(\\*{2})": "杀戮欲望",
  2824. "(\\*{2})和本能": "欲望和本能",
  2825.  
  2826. // === 呻吟 ===
  2827. "不堪重负的(\\*{2})": "不堪重负的呻吟",
  2828. "(\\*{2})声": "呻吟声",
  2829. "颤抖(\\*{2})": "颤抖呻吟",
  2830. "(\\*{2})颤抖": "呻吟颤抖",
  2831.  
  2832. // === 独立 ===
  2833. "宣布(\\*{2})": "宣布独立",
  2834. "(\\*{2})空间": "独立空间",
  2835.  
  2836. // === 荡漾 ===
  2837. "波纹(\\*{2})": "波纹荡漾",
  2838.  
  2839. // === 喘息 ===
  2840. "(\\*{2})之机": "喘息之机",
  2841.  
  2842. // === 大波 ===
  2843. "一(\\*{2})": "一大波",
  2844.  
  2845. // === 上供 ===
  2846. "(\\*{2})奉": "上供奉",
  2847.  
  2848. // === 奸淫 ===
  2849. "(\\*{2})掳掠": "奸淫掳掠",
  2850.  
  2851. // === 失身 ===
  2852. "有(\\*{2})份": "有失身份",
  2853.  
  2854. // === 六合 ===
  2855. "(\\*{2})八荒": "六合八荒",
  2856.  
  2857. // === 人祸 ===
  2858. "天灾(\\*{2})": "天灾人祸",
  2859.  
  2860. // === 轮红 ===
  2861. "一(\\*{2})日": "一轮红日",
  2862.  
  2863. // === 西藏 ===
  2864. "东躲(\\*{2})": "东躲西藏",
  2865.  
  2866. // === 被操 ===
  2867. "(\\*{2})纵": "被操纵",
  2868.  
  2869. // === 穷屌 ===
  2870. "(\\*{2})丝": "穷屌丝",
  2871.  
  2872. // === 销魂 ===
  2873. "(\\*{2})滋味": "销魂滋味",
  2874.  
  2875. // === 色水 ===
  2876. "血(\\*{2})晶": "血色水晶",
  2877.  
  2878. // === 偷用 ===
  2879. "偷(\\*{2})": "偷偷用",
  2880.  
  2881. // === 乳交 ===
  2882. "水(\\*{2})融": "水乳交融",
  2883.  
  2884.  
  2885. // === 多字替换 ===
  2886. "cao之过急": "操之过急", "chunguang大泄": "春光大泄",
  2887. "大公无si": "大公无私",
  2888. "fu道人家": "妇道人家", "放sōng'xià来": "放松下来",
  2889. "奸yin掳掠": "奸淫掳掠",
  2890. "空dangdang": "空荡荡",
  2891. "突发qing况": "突发情况",
  2892. "yin奉阳违": "阴奉阳违", "一yin一阳": "一阴一阳",
  2893.  
  2894. // === 双字替换 ===
  2895. "暧m[eè][iì]":"暧昧",
  2896. "bàn\\s*fǎ":"办法", "bucuo":"不错", "不liáng":"不良", "b[ěe]i(\\s|&nbsp;)*j[īi]ng":"北京", "bǐ\\s*shǒu":"匕首", "半shen":"半身", "b[ìi]j[ìi]ng":"毕竟", "报(了?)jing":"报$1警", "bèi'pò":"被迫", "包yǎng":"包养", "(?:biǎo|婊\\\\?)子":"婊子", "biǎo\\s*xiàn\\s*":"表现",
  2897. "chifan":"吃饭", "ch[oō]ngd[oò]ng":"冲动", "chong物":"宠物", "cao(练|作)":"操$1", "出gui":"出轨", "chu\\s*xian":"出现", "缠mian":"缠绵", "成shu":"成熟", "(?:赤|chi)\\s*lu[oǒ]":"赤裸", "春guang":"春光", "chun风":"春风", "chuang伴":"床伴", "沉mi":"沉迷", "沉lun":"沉沦", "刺ji":"刺激", "chao红":"潮红", "初chun":"初春", ""chi\\s*luo"":"赤裸", "cí\\s*zhí":"辞职",
  2898. "dān\\s*xīn":"当心", "dang校":"党校", "da子":"鞑子", "大tui":"大腿", "dǎ\\s*suàn":"打算", "dá\\s*àn":"答案", "dài\\s*lǐ":"代理", "dengdai":"等待", "电huà":"电话", "diàn\\s*huà":"电话", "diàn\\s*yǐng":"电影", "diao丝":"屌丝", "d[úu](?:\\s|&nbsp;|<br/>)*l[ìi]":"独立", "d[uú]\\s{0,2}c[áa]i":"独裁", "d?[iì]f[āa]ng":"地方", "d[ìi]\\s*d[ūu]":"帝都", "di国|帝guo":"帝国", "du[oò]落":"堕落", "坠luò":"坠落",
  2899. "f[ǎa]ngf[óo]":"仿佛", "fei踢":"飞踢", "fēi\\s*wén":"飞吻", "feng流":"风流", "风liu":"风流", "f[èe]nn[ùu]":"愤怒", "fǎn\\s*yīng":"反应", "fú\\s*wù":"服务", "fù\\s*chóu":"复仇",
  2900. "gao潮":"高潮", "高氵朝":"高潮", "gāo\\s*xìng\\s*":"高兴", "干chai":"干柴", "勾yin":"勾引", "gu[oò]ch[ée]ng":"过程", "gu[āa]n\\s*x[iì]":"关系", "官\\s*fāng":"官方", "g[ǎa]nji[àa]o":"感觉", "国wu院":"国务院", "gù\\s*yì\\s*":"故意", "guofen":"过分", "guān\\s*fāng":"官方",
  2901. "hā\\s*hā\\s*":"哈哈", "h[aǎ]ode":"好的", "hù士":"护士", "火qiang":"火枪", "huó\\s*dòng":"活动", "há'guó":"韩国", "han住":"含住", "hai洛因":"海洛因", "红fen":"红粉", "火yao":"火药", "h[ǎa]oxi[àa]ng":"好像", "hu[áa]ngs[èe]":"黄色", "皇d[ìi]":"皇帝", "昏昏yu睡":"昏昏欲睡", "回dang":"回荡", "huí\\s*qù\\s*":"回去", "hé\\s*shì\\s*":"合适", "hàn\\s*jiān":"汉奸",
  2902. "jian(臣|细)":"奸$1", "奸yin":"奸淫", "jiànmiàn":"见面", "jian货":"贱货", "jing察":"警察", "jǐng\\s*chá":"警察", "j[ìi]nháng":"进行", "jīng\\s*guò":"经过", "ji烈":"激烈", "j[iì](nv|女)":"妓女", "jirou":"鸡肉", "ji者":"记者", "jì\\s*xù\\s*":"继续", "ju花":"菊花", "j[īi]动":"激动", "jili[èe]":"激烈", "肌r[òo]u":"肌肉", "ji射":"激射", "ji[ēe]ch[uù]":"接触", "jiù\\s*shì":"就是", "j[ùu]li[èe]":"剧烈", "jǐng惕":"警惕", "节cao":"节操", "浸yin":"浸淫", "jù\\s*jué\\s*":"拒绝", "jue色":"角色",
  2903. "k[ěe]n[ée]ng":"可能", "开bao":"开苞", "k[àa]o近":"靠近", "口wen":"口吻", "kankan":"看看",
  2904. "ling辱":"凌辱", "luan蛋":"卵蛋", "脸sè":"脸色", "lu出":"露出", "流máng":"流氓", "lun理":"伦理", "lì\\s*qì":"力气", "lán\\s*jié":"拦截", "lìng\\s*lèi":"另类", "lè\\s*suǒ":"勒索", "lòudòng":"漏洞",
  2905. "m[ǎa]ny[ìi]":"满意", "m[ǎa]sh[àa]ng":"马上", "m[ée]iy[oǒ]u":"没有", "mei国":"美国", "měi\\s*nǚ":"美女", "mèi\\s*mèi":"妹妹", "m[íi]ngb[áa]i":"明白", "迷huan":"迷幻", "mi茫":"迷茫", "mó\\s*yàng":"模样", "m[íi]n\\s{0,2}zh[ǔu]":"民主", "迷jian":"迷奸", "mimi糊糊":"迷迷糊糊", "mì\\s*shū":"秘书", "末(?:\\s|<br/?>)*ì":"末日", "面se":"面色", "mengmeng":"蒙蒙", "màn\\s*huà":"漫画",
  2906. "nàme":"那么", "n[ǎa]o\\s*d[àa]i":"脑袋", "n[ée]ngg[oò]u":"能够", "nán\\s{0,2}hǎi":"那会", "内jian":"内奸", "[内內]y[iī]":"内衣", "内ku":"内裤",
  2907. "pi[áa]o客":"嫖客", "p[áa]ngbi[āa]n":"旁边",
  2908. "q[íi]gu[àa]i":"奇怪", "qì\\s*chē":"汽车", "qing\\s*(ren|人)":"情人", "qin兽":"禽兽", "q[iī]ngch[uǔ]":"清楚", "què\\s*dìng":"确定", "球mi":"球迷", "青chun":"青春", "青lou":"青楼", "qingkuang":"情况", "qiang[ \\s]*jian":"强奸",
  2909. "re\\s*nao":"热闹", "r[úu]gu[oǒ]":"如果", "r[oó]ngy[ìi]":"容易", "ru(房|白色)":"乳$1", "rén员":"人员", "rén形":"人形", "人chao":"人潮", "renmen":"人名", "ruǎn\\s*jiàn":"软件", "rì\\s*běn":"日本", "日\\s*běn":"日本",
  2910. "shàng\\s*mén":"上门", "上jiang":"上将", "she(门|术|手|程|击)":"射$1", "sudu":"速度", "shú\\s*nǚ":"熟女", "shuijue":"睡觉", "shide":"是的", "sh[iì]ji[eè]":"世界", "sh[ií]ji[aā]n":"时间", "sh[ií]h[oò]u":"时候", "sh[ií]me":"什么", "si人":"私人", "shi女":"侍女", "shi身":"失身", "sh[ūu]j[ìi]":"书记", "shu女":"熟女", "shu[ \\s]?xiong":"酥胸", "(?:上|shang)chuang":"上床", "shǒu\\s*jī":"手机", "呻y[íi]n":"呻吟", "sh[ēe]ngzh[íi]":"生殖", "深gu":"深谷", "双xiu":"双修", "生r[ìi]":"生日", "si盐":"私盐", "shi卫":"侍卫", "si下":"私下", "sao扰":"骚扰", "shuang\\s*feng":"双峰", "shǎo\\s*fù":"少妇", "shì\\s*pín":"视频", "shè\\s*xiàng":"摄像",
  2911. "t[uū]r[áa]n":"突然", "tiaojiao":"调教", "tí\\s*gòng":"提供", "偷qing":"偷情", "推dao":"推倒", "脱guang":"脱光", "t[èe]bi[ée]":"特别", "t[ōo]nggu[òo]":"通过", "同ju":"同居", "tian来tian去":"舔来舔去",
  2912. "w[ēe]ixi[ée]":"威胁", "wèizh[ìi]":"位置", "wei员":"委员", "w[èe]nti":"问题", "wèi\\s*dào\\s*":"味道", "wú\\s*nài":"无奈", "wǔ\\s*qì":"武器", "weilai":"未来",
  2913. "xiu长":"修长", "亵du":"亵渎", "xing福":"幸福", "xìng\\s*yùn":"幸运", "小bo":"小波", "小niū":"小妞", "xiong([^a-z])":"胸$1", "小tui":"小腿", "xiang港":"香港", "xiàohuà":"笑话", "xiāo\\s*shòu":"销售", "xiàn\\'zhì":"限制", "xiàn\\s*jīn":"现金", "xiāng\\s*zǐ":"箱子", "xiōng\\s*dì":"兄弟", "选zé":"选择", "xìn\\s*hào":"信号", "xìng\\s*gǎn":"性感", "xiǎo\\s*jiě":"小姐", "xìn\\s*hào":"信号", "xià\\s*zhù":"下注",
  2914. "yì\\s*wài\\s*":"意外", "yin(冷|暗|谋|险|沉|沟|癸派|后)":"阴$1", "y[iī]y[àa]ng":"一样", "y[īi]di[ǎa]n":"一点", "yī\\s*zhèn":"一阵", "y[ǐi]j[īi]ng":"已经", "疑huo":"疑惑", "yí\\s*huò":"疑惑", "影mi":"影迷", "yin荡":"淫荡", "yin贼":"淫贼", "阳w[ěe]i":"阳痿", "yao头":"摇头", "yaotou":"摇头", "摇tou":"摇头", "yezhan":"野战", "you饵":"诱饵", "(?:you|诱)(?:惑|huo)":"诱惑", "you导":"诱导", "引you":"引诱", "you人":"诱人", "youshi":"有事", "you\\s*xiu":"优秀", "御yòng":"御用", "旖ni":"旖旎", "yu念":"欲念", "you敌深入":"诱敌深入", "影she":"影射", "牙qian":"牙签", "一yè情":"一夜情", "yīng\\s*yǔ":"英语",
  2915. "z[iì]j[iǐ]":"自己", "z[ìi](?:\\s|<br/?>|&nbsp;)*y[oó]u":"自由", "zh[iī]d?[àa]u?o":"知道", "zixin":"自信", "zhì'fú":"制服", "zhì\\s*fú":"制服", "zha药":"炸药", "zhan有":"占有", "zhào\\s*piàn":"照片", "zhè\\s*gè":"这个", "政f[ǔu]|zheng府":"政府", "zh[èe]ng\\s{0,2}f[uǔ]":"政府", "zong理":"总理", "zh[ōo]ngy[āa]ng":"中央", "中yang":"中央", "zu[oǒ]\\s*y[oò]u":"左右", "zhǔ\\s*dòng":"主动", "zh[oō]uw[ée]i":"周围", "zhōu\\s*nián":"周年", "中nan海":"中南海", "中j委":"中纪委", "中zu部":"中组部", "政zhi局":"政治局", "(昨|一|时|余)(?:<br/?>|&nbsp;|\\s)*ì":"$1日", "照she":"照射", "zhǔn\\s*bèi\\s*":"准备", "zhu义":"主义",
  2916.  
  2917. "</p>\\n<p>\\s*ì":"日",
  2918.  
  2919. '曹艹': '曹操',
  2920. 'JI昂': '激昂',
  2921. '□□无暇': '自顾无暇',
  2922. '法律/界': '法律界',
  2923. '人/类': '人类',
  2924. '恐怖/主义': '恐怖主义',
  2925. '颠/覆': '颠覆',
  2926. '民.事.司.法.裁.判': '民事司法裁判',
  2927. '南海/问题': '南海问题',
  2928. '圈圈/功': '法轮功',
  2929. '镇/压': '镇压',
  2930. '赤.裸': '赤裸',
  2931. '欲·望': '欲望',
  2932. 'nv真': '女真',
  2933. '土gai': '土改',
  2934. '狗·屎': '狗屎',
  2935. 'du立': '独立',
  2936. '发sao': '发骚',
  2937. '奸/夫/淫/妇': '奸夫淫妇',
  2938. '爱qing': '爱情',
  2939. '抚mo': '抚摸',
  2940. '神qing': '神情',
  2941. '公~务~员': '公务员',
  2942. '原着': '原著',
  2943. '□□部分': '高潮部分',
  2944. '角□□面': '角色情面',
  2945. '艹': '操',
  2946. '淫/靡/香/艳': '淫靡香艳',
  2947. '毒丨药': '毒药',
  2948. '登6': '登陆',
  2949. '天□□美': '天性爱美',
  2950. '双丨飞': '双飞',
  2951. '高chao': '高潮',
  2952. 'pi股': '屁股',
  2953. '情/趣': '情趣',
  2954. '情/欲': '情欲',
  2955. '炸/弹': '炸弹',
  2956. '赤/身': '赤身',
  2957. '果/体': '裸体',
  2958. 'zhong国': '中国',
  2959. '帝国#主义': '帝国主义',
  2960. '形形□□': '形形色色',
  2961. 'yuwang': '欲望',
  2962. 'shuangtui': '双腿',
  2963. '城/管': '城管',
  2964. '调丨教': '调教',
  2965. '银/行/卡': '银行卡',
  2966. '裸/体': '裸体',
  2967. '光/裸': '光裸',
  2968. '嫩/女': '嫩女',
  2969. '维/谷': '维谷',
  2970. '开□□谈': '开始交谈',
  2971. '破碎的□□': '破碎的呻吟',
  2972. 'pi霜': '砒霜',
  2973. 'ma醉': '麻醉',
  2974. '麻zui': '麻醉',
  2975. 'nue杀': '虐杀',
  2976. '后gong': '后宫',
  2977. '林荫dao': '林荫道',
  2978. '分/身': '分身',
  2979. '克/隆': '克隆',
  2980. '性/需要': '性需要',
  2981. '黑/帮': '黑帮',
  2982. '政-府': '政府',
  2983. '八/九': '八九',
  2984. '不~着~寸~缕': '不着寸缕',
  2985. '肉~体': '肉体',
  2986. '蹲□子': '蹲下身子',
  2987. 'ji情': '激情',
  2988. 'xie恶': '邪恶',
  2989. 'Z国': '中国',
  2990. '创/世': '创世',
  2991. '紫jin城': '紫禁城',
  2992. '□□在外': '裸露在外',
  2993. '光怪6离': '光怪陆离',
  2994. '邪/教': '邪教',
  2995. '粗bao': '粗暴',
  2996. 'yin邪': '淫邪',
  2997. '小biao砸': '小婊砸',
  2998.  
  2999. '牛1b': '牛b', '微1博': '微博', '内1衣': '内衣',
  3000. };
  3001.  
  3002. const replaceAll = [
  3003. // 长文字替换
  3004. // 排序代码:newArr = arr.sort((a, b) => { var diff = a.charCodeAt(1) - b.charCodeAt(1); if (diff == 0) return b.length - a.length; return diff; })
  3005. '本站域名已经更换为,老域名已经停用,请大家重新收藏,并使用新域名访问。',
  3006. "\\(跪求订阅、打赏、催更票、月票、鲜花的支持!\\)",
  3007. "\\(?未完待续请搜索飄天文學,小说更好更新更快!",
  3008. "\\(跪求订阅、打赏、催更票、月票、鲜花的支持!",
  3009. "\\(看小说到网\\)",
  3010. "\\(未完待续。\\)",
  3011. "\\(本章完\\)",
  3012. "16977小游戏每天更新好玩的小游戏,等你来发现!",
  3013. "(800小说网 www.800Book.net 提供Txt免费下载)最新章节全文阅读-..-",
  3014. "(800小说网 www.800Book.net 提供Txt免费下载)",
  3015. "\\[800\\]\\[站页面清爽,广告少,",
  3016. "\\[看本书最新章节请到求书 .\\]",
  3017. "(\\s*君子聚义堂)",
  3018. "readx;",
  3019. "txt电子书下载/",
  3020. "txt全集下载",
  3021. "txt小说下载",
  3022. "\\|优\\|优\\|小\\|说\\|更\\|新\\|最\\|快\\|www.uuxs.cc\\|",
  3023. "\\|每两个看言情的人当中,就有一个注册过可°乐°小°说°网的账号。",
  3024. "思ˊ路ˋ客,更新最快的!",
  3025. "恋上你看书网 630bookla ,最快更新.*",
  3026. ",举报后维护人员会在两分钟内校正章节内容,请耐心等待,并刷新页面。",
  3027. "追书必备",
  3028. "-优-优-小-说-更-新-最-快-www.UUXS.CC-",
  3029. "-优-优-小-说-更-新-最-快x",
  3030. "来可乐网看小说",
  3031. "纯文字在线阅读本站域名手机同步阅读请访问",
  3032. "本文由  首发",
  3033. "樂文小说",
  3034. '最快更新无错小说阅读,请访问 请收藏本站阅读最新小说!',
  3035. "最新章节全文阅读看书神器\\.yankuai\\.",
  3036. "最新章节全文阅读(..首发)",
  3037. "最新章节全文阅读【首发】",
  3038. "最新章节全文阅读",
  3039. "看本书最新章节请到800小说网(www.800book.net)",
  3040. "(本章未完,请翻页)",
  3041. "手机用户请浏览m.biqugezw.com阅读,更优质的阅读体验。",
  3042. "手机用户请浏览阅读,更优质的阅读体验。",
  3043. "阅读,更优质的阅读体验。",
  3044. "手机最省流量无广告的站点。",
  3045. "手机看小说哪家强手机阅",
  3046. "如果你喜欢本站[〖]?一定要记住[】]?(?:网址|地址)哦",
  3047. "看清爽的小说就到",
  3048. "请用搜索引擎(?:搜索关键词)?.*?完美破防盗章节,各种小说任你观看",
  3049. "完美破防盗章节,请用搜索引擎各种小说任你观看",
  3050. "破防盗章节,请用搜索引擎各种小说任你观看",
  3051. "(?:搜索引擎)?各种小说任你观看,破防盗章节",
  3052. "章节错误,点此举报\\(免注册\\)",
  3053. "热门小说最新章节全文阅读.。 更新好快。",
  3054. "【阅读本书最新章节,请搜索800】",
  3055. "亲,百度搜索眼&amp;快,大量小说免费看。",
  3056. "亲,眼&快,大量小说免费看。",
  3057. '下载免费阅读器!!',
  3058. '笔趣阁&nbsp;.,最快更新.*最新章节!',
  3059. '请大家搜索(书迷楼)看最全!更新最快的小说',
  3060. '更新快无广告。',
  3061. '【鳳.{1,2}凰.{1,2}小说网 更新快 无弹窗 请搜索f.h.xiao.shuo.c.o.m】',
  3062. '【可换源APP看书软件:书掌柜APP或直接访问官方网站shuzh.net】',
  3063. '[●★▲]手机下载APP看书神器.*',
  3064. "m.?手机最省流量的站点。",
  3065. 'm.?手机最省流量.无广告的站点。',
  3066. '底部字链推广位',
  3067. 'us最快',
  3068. 'APPapp',
  3069. '久看中文网首发',
  3070. '顶点小说 23US.com更新最快',
  3071.  
  3072. // 复杂规则的替换
  3073. '(看小说到|爱玩爱看就来|就爱上|喜欢)?(\\s|<|>|&| |[+@@=:;``%?》《〈︾-])?[乐樂](\\s|&lt;|&gt;|&amp;|&nbsp;|[+@@=:;``%?》《〈︾-])?[文].*?[说說][网]?[|]?(.*(3w|[wωWw]{1,3}|[Mm]).*[mMm])?[}。\\s]?(乐文小说)?',
  3074. '(本文由|小说)?(\\s| )?((3w|[wWw]{1,3}|[Mm]).)?\\s?[lしlL][wωWw][xχXx][sSs][55][22][00].*[mMm][|\\s]?(首发(哦亲)?)?',
  3075. '([『【↑△↓@︾]+[\u4E00-\u9FA5]){2,6}[】|]',
  3076.  
  3077. // 包含 \P 的替换
  3078. '\\P{1,2}[顶頂].{1,3}[点小].*?o?[mw,]',
  3079. '\\P.?长.{1,2}风.{1,2}文.{1,2}学.*?[tx]',
  3080. '\\P无.错.*?[cC][oO][mM]',
  3081. '[;\\(]顶.{0,2}点.小说',
  3082. '2长2风2文2学,w¢$',
  3083. '》长>风》',
  3084.  
  3085. // 包含 .* 的,可能有多余的替换
  3086. '看无防盗章节的小说,请用搜索引擎搜索关键词.*',
  3087. '(?:完美)?破防盗章节,请用搜索引擎搜索关键词.*',
  3088. '搜索引擎搜索关键词,各种任你观看,破防盗章节',
  3089. '破防盗完美章节,请用搜索引擎.*各种小说任你观看',
  3090. '如您已(?:閱讀|阅读)到此章节.*?敬请记住我们新的网址\\s*。',
  3091. '↗百度搜:.*?直达网址.*?↖',
  3092. "[:《〈|~∨∟∑]{1,2}长.{1,2}风.*?et",
  3093. '\\[限时抢购\\].*',
  3094. '支持网站发展.逛淘宝买东西就从这里进.*',
  3095. 'ps[::]想听到更多你们的声音,想收到更多你们的建议,现在就搜索微信公众号“qdread”并加关注,给.*?更多支持!',
  3096. '(?:ps[::])?看《.*?》背后的独家故事.*?告诉我吧!',
  3097. '(?天上掉馅饼的好活动.*?微信公众号!)?',
  3098. '(微信添加.*qdread微信公众号!)',
  3099. 'jiemei如您已阅读到此章节,请移步到.*?\\[ads:本站换新网址啦,速记方法:,.\\]',
  3100. '先给自己定个小目标:比如收藏笔趣阁.*',
  3101. '请记住本书首发域名.*',
  3102. '记住手机版网址.*',
  3103. '.*关注微信公众号.*',
  3104. '一秒记住.*',
  3105.  
  3106. // 短文字替换
  3107. '\\[txt全集下载\\]',
  3108. '\\[\\s*超多好看小说\\]',
  3109. '⊙四⊙五⊙中⊙文☆→',
  3110. '\\[ads:本站换新网址啦,速记方法:.*?\\]',
  3111. '[》《|~]无(?:.|&gt;)错(?:.|&gt;)小说',
  3112. '`无`错`小说`www.``com', '+无+错+小说+3w++',
  3113. '\\|优\\|优\\|小\\|说\\|更\\|新\\|最\\|快X',
  3114. '▲∴', '8,ww←',
  3115. /www.23+?[Ww][Xx].[Cc]om/ig,
  3116. /热门推荐:、+/g,
  3117. /h2&gt;/g,
  3118. '[《〈》>\\+|~[\\]]无\\1错\\1', '》无>错》',
  3119.  
  3120. '女凤免费小说抢先看', '女凤小说网全文字 无广告',
  3121. '乐文小说网?', '《乐〈文《小说', '乐文移动网', '頂点小说', '頂點小說',
  3122. '追小说哪里快去眼快',
  3123. '\\[书库\\].\\[774\\]\\[buy\\].kuai',
  3124. 'www.938xs.com',
  3125.  
  3126. /'ads_wz_txt;',|百度搜索|无弹窗小说网|更新快无弹窗纯文字|高品质更新|小说章节更新最快|\(百度搜.\)|全文字手打|“”&nbsp;看|无.弹.窗.小.说.网|追书网|〖∷∷无弹窗∷纯文字∷ 〗/g,
  3127. ];
  3128.  
  3129. // import _ from 'underscore'
  3130.  
  3131. // 单字替换,可能会误替换,所以需要特殊处理
  3132. var oneWordReplace = {
  3133. "b[āà]ng":"棒","bào":"爆","bà":"吧","bī":"逼","bō":"波", "biàn":"便",
  3134. "cāo":"操", "cǎo":"草", "cào":"操", "chāng":"娼", "chang":"娼", "cháo":"潮", "chā":"插", "chéng":"成", "chōu":"抽", "chuáng":"床", "chún":"唇", "chūn":"春", "cuō":"搓", "cū":"粗",
  3135. "dǎng":"党", "dàng":"荡", "dāo":"刀", "dòng":"洞", "diao":"屌", "diǎn":"点",
  3136. "fǎ":"法", "féi":"肥", "fù":"妇",
  3137. "guān":"官",
  3138. "hán":"含", "hóu":"喉", "hòu":"后", "h(u)?ā":"花", "huá":"华", "huì":"会", "huò":"惑", "hùn":"混", "hún":"魂",
  3139. "jiǔ":"九", "j[īi]ng":"精", "jìn":"禁", "jǐng":"警", "jiāng":"江", "jiān":"奸", "jiāo":"交", "jūn":"军", "jū":"拘", "jú":"局", "jī":"激", "激ān":"奸",
  3140. "kù":"裤", "kàn":"看",
  3141. "[1l]àng":"浪", "liáo":"撩", "liú":"流", "lì":"莉", "liè":"烈", "[1l]uàn":"乱", "lún":"伦", "luǒ":"裸", "lòu":"露", "[l1]ù":"露", "lǜ":"绿", "liàn":"练",
  3142. "mǎi":"买", "mài":"卖", "máo":"毛", "mā":"妈", "méng":"蒙", "mén":"门", "miè":"灭", "mí":"迷", "mì":"蜜", "mō":"摸", "miàn":"面",
  3143. "nǎi":"奶", "nèn":"嫩", "niào":"尿", "niē":"捏", "nòng":"弄", "nǚ":"女",
  3144. "pào":"炮", "piàn":"片", "pò":"破",
  3145. "qi[āa]ng":"枪", "qíng":"情", "qīn":"亲", "qiú":"求", "quán":"全", "qù":"去",
  3146. "rén":"人", "r[ìi]":"日", "rǔ":"乳",
  3147.  
  3148. // s
  3149. "sǎ":"洒", "sāo":"骚", "sǎo":"骚", "sè":"色", "se":"色", "shā":"杀",
  3150. "shēn":"身", "shēn":"呻", // 2个重复的,误替换且是单字怎么办
  3151. "shén":"神", "shè":"射", "shǐ":"屎", "shì":"侍", "sǐ":"死", "sī":"私", "shǔn":"吮", "sǔn":"吮", "sū":"酥", "shào":"绍",
  3152.  
  3153. "tān":"贪", "tiǎn":"舔", "t[ǐi]ng":"挺", "tǐ":"体", "tǒng":"捅", "tōu":"偷", "tou":"偷", "tuǐ":"腿", "tūn":"吞", "tún":"臀", "tiáo":"调", "tài":"态", "tào":"套",
  3154. "wēn":"温", "wěn":"吻",
  3155. "xiǎo":"小", "xiào":"笑", "xìng":"性", "xing":"性", "xiōng":"胸", "xī":"吸", "xí":"习", "xì":"系", "xìn":"信", "xué":"穴", "xuè":"穴", "xùe":"穴", "xuan":"宣", "xiàng":"象",
  3156. "yāng":"央", "yàn":"艳", "yīn":"阴", "yào":"药", "yé":"爷", "yòu":"诱", "zàng":"脏", "y[ùu]":"欲", "yín":"淫", "yì":"意", "yà":"讶",
  3157. "zhēn":"针", "zēn":"针", "zhà":"炸", "zhèng":"政", "zǒu":"走", "zuì":"罪", "zuò":"做", "zhōng":"中",
  3158. };
  3159.  
  3160. var replaceFix = {
  3161. // ===误替换还原===
  3162. "碧欲":"碧玉", "美欲":"美玉","欲石":"玉石","惜欲":"惜玉","宝欲":"宝玉",
  3163. "品性":"品行", "德性":"德行",
  3164. "波ok":"book", "波SS":"BOSS",
  3165.  
  3166. // ===其他修正===
  3167. "弥俩":"你俩",
  3168. "妳":"你",
  3169. "圞|垩|卝|龘":"",
  3170. "大6":"大陆",
  3171. };
  3172.  
  3173. function extendRule(replaceRule) {
  3174. _.each(oneWordReplace, function(value, key) {
  3175. // 这个替换会把 yùn 替换为 yù
  3176. // replace['\\b' + key + '(?:\\b|\\s*)'] = value;
  3177.  
  3178. // 这个不会替换 rén: shā rén偿命 => 杀 rén偿命
  3179. // replaceRule['([^a-z\\s])' + key + '(?![a-z])'] = '$1' + value;
  3180.  
  3181. replaceRule['\\b' + key + '(?![a-z])'] = value;
  3182. });
  3183.  
  3184. _.extend(replaceRule, replaceFix);
  3185. }
  3186.  
  3187.  
  3188.  
  3189. // test()
  3190.  
  3191. var CHAR_ALIAS = {
  3192. '\\P': '[\\u2000-\\u2FFF\\u3004-\\u303F\\uFE00-\\uFF60\\uFFC0-\\uFFFF]', // 小说中添加的特殊符号
  3193. };
  3194.  
  3195. // ===== 自动尝试的规则 =====
  3196. var Rule = {
  3197. titleRegExp: /第?\s*[一二两三四五六七八九十○零百千万亿0-91234567890]{1,6}\s*[章回卷节折篇幕集话話]/i,
  3198. titleReplace: /^章节目录|^文章正文|^正文|全文免费阅读|最新章节|\(文\)/,
  3199.  
  3200. // nextRegExp: /[上前下后][一]?[页张个篇章节步]/,
  3201. nextSelector: "a[rel='next'], a:contains('下一页'), a:contains('下一章'), a:contains('下一节'), a:contains('下页')",
  3202. prevSelector: "a[rel='prev'], a:contains('上一页'), a:contains('上一章'), a:contains('上一节'), a:contains('上页')",
  3203. // 忽略的下一页链接,匹配 href
  3204. nextUrlIgnore: [
  3205. /(?:(?:index|list|last|LastPage|end)\.)|BuyChapterUnLogin|^javascript:/i,
  3206.  
  3207. // qidian
  3208. /BookReader\/LastPageNew\.aspx/i,
  3209. /read\.qidian\.com\/BookReader\/\d+,0\.aspx$/i,
  3210. /read\.qidian\.com\/$/i,
  3211. /free\.qidian\.com\/Free\/ShowBook\.aspx\?bookid=/i,
  3212.  
  3213. /book\.zongheng\.com\/readmore/i,
  3214. /www\.shumilou\.com\/to-n-[a-z]+-\d+\.html/i,
  3215. /\/0\.html$/i,
  3216. ],
  3217. nextUrlCompare: /\/\d+(_\d+)?\.html?$|\/wcxs-\d+-\d+\/$|chapter-\d+\.html$|\/\d+_\d+\/$/i, // 忽略的下一页链接(特殊),跟上一页比较
  3218.  
  3219. // 按顺序匹配,匹配到则停止。econtains 完全相等
  3220. indexSelectors: ["a[href='index.html']", "a:contains('返回书目')", "a:contains('章节目录')", "a:contains('章节列表')",
  3221. "a:econtains('最新章节')", "a:contains('回目录')","a:contains('回书目')", "a:contains('目 录')", "a:contains('目录')"],
  3222.  
  3223. contentSelectors: ["#pagecontent", "#contentbox", "#bmsy_content", "#bookpartinfo", "#htmlContent",
  3224. "#text_area", "#chapter_content", "#chapterContent", "#partbody", "#BookContent", "#read-content",
  3225. "#article_content", "#BookTextRead", "#booktext", "#book_text", "#BookText", "#readtext", "#readcon",
  3226. "#TextContent", "#text_c", "#txt_td", "#TXT", "#txt", "#zjneirong",
  3227. ".novel_content", ".readmain_inner", ".noveltext", ".booktext", ".yd_text2",
  3228. "#contentTxt", "#oldtext", "#a_content", "#contents", "#content2", "#contentts", "#content1", "#content", ".content"
  3229. ],
  3230.  
  3231. // 尝试查找书名。顶部章节导航的最后一个链接可能是书名。
  3232. bookTitleSelector: [
  3233. '.h1title > .shuming > a[title]',
  3234. '.chapter_nav > div:first > a:last',
  3235. '#header > .readNav > span > a:last',
  3236. 'div[align="center"] > .border_b > a:last',
  3237. '.ydselect > .weizhi > a:last',
  3238. '.bdsub > .bdsite > a:last',
  3239. '#sitebar > a:last',
  3240. '.con_top > a:last',
  3241. '.breadCrumb > a:last',
  3242. ],
  3243. bookTitleReplace: [
  3244. '全文阅读$',
  3245. ],
  3246.  
  3247. contentRemove: "script, iframe", // 内容移除选择器
  3248. removeLineRegExp: /<p>[ \s。;,!\.∷〖]*<\/p>/g, // 移除只有一个字符的行
  3249.  
  3250. // 以下不常改
  3251. replaceBrs: /(<br[^>]*>[ \n\r\t]*){1,}/gi, // 替换为<p>
  3252. };
  3253.  
  3254. Rule.specialSite = sites;
  3255.  
  3256. Rule.replace = replace;
  3257.  
  3258. extendRule(Rule.replace);
  3259.  
  3260. // ===== 全局移除,在替换 <br> 为 \n 之后 =====
  3261. Rule.replaceAll = replaceAll;
  3262.  
  3263.  
  3264. // 自定义的
  3265. Rule.customRules = [];
  3266. Rule.customReplace = {};
  3267.  
  3268. Rule.parseCustomReplaceRules = function(str) {
  3269. var arr = str.split(/\n/);
  3270. var rules = {};
  3271. _.each(arr, function(b) {
  3272. var pos = b.indexOf('=');
  3273. if (pos === -1) return;
  3274.  
  3275. var key = b.substring(0, pos),
  3276. value = b.substring(pos + 1, b.length);
  3277. rules[key] = value;
  3278. });
  3279. return rules;
  3280. };
  3281.  
  3282. // 内容需要 ajax 的 className
  3283. const READER_AJAX = "reader-ajax";
  3284.  
  3285. const autoBookTitleSelector = Rule.bookTitleSelector;
  3286.  
  3287. function autoGetBookTitle($doc) {
  3288. let bookTitle = '';
  3289. // 依次获取
  3290. for (let s of autoBookTitleSelector) {
  3291. let $node = $doc.find(s);
  3292. if ($node.length === 1) {
  3293. bookTitle = $node.text();
  3294. break
  3295. }
  3296. }
  3297.  
  3298. // 排除一些无效的?
  3299. C.log('autoGetBookTitle', bookTitle);
  3300.  
  3301. return bookTitle
  3302. }
  3303.  
  3304. function getElemFontSize(_heading) {
  3305. var fontSize = 0;
  3306. var _heading_style = window.getComputedStyle(_heading, null);
  3307. if (_heading_style) {
  3308. // firefox57 2017年9月10日 会错误
  3309. try {
  3310. var str = _heading_style.getPropertyValue("font-size") || 0;
  3311. fontSize = parseInt(str, 10);
  3312. } catch(e) { }
  3313. }
  3314.  
  3315. return fontSize
  3316. }
  3317.  
  3318. function Parser(){
  3319. this.init.apply(this, arguments);
  3320. }
  3321.  
  3322. Parser.prototype = {
  3323. constructor: Parser,
  3324. get contentTxt() { // callback 才有用
  3325. var text = $('<div>').html(this.content).text().trim();
  3326.  
  3327. // 解决第二个段落和第一个锻炼合在一起的问题
  3328. text = text.replace(/([^\n])  /, '$1\n  ');
  3329.  
  3330. return text;
  3331. },
  3332.  
  3333. init: function (info, doc, curPageUrl) {
  3334. this.info = info || {};
  3335. this.doc = doc;
  3336. this.$doc = $(doc);
  3337. this.curPageUrl = curPageUrl || doc.URL;
  3338. this._curPageHost = getUrlHost(this.curPageUrl); // 当前页的 host,后面用到
  3339.  
  3340. // 设置初始值
  3341. this.isTheEnd = false;
  3342. this.isSection = false;
  3343. },
  3344. applyPatch: function(){
  3345. var contentPatch = this.info.contentPatch;
  3346. if(contentPatch){
  3347. try {
  3348. contentPatch.call(this, this.$doc);
  3349. C.log("Apply Content Patch Success.");
  3350. } catch (e) {
  3351. C.log("Error: Content Patch Error!", e);
  3352. }
  3353. }
  3354. },
  3355. applyAsyncPatch: function(callback) {
  3356. var contentPatch = this.info.contentPatchAsync;
  3357. if(contentPatch){
  3358. try {
  3359. contentPatch.call(this, this.$doc, callback.bind(this));
  3360. C.log("Apply Content Patch[Async] Success.");
  3361. } catch (e) {
  3362. C.log("Error: Content Patch[Async] Error!", e);
  3363. }
  3364. } else {
  3365. callback();
  3366. }
  3367. },
  3368. getAll: function(callback){
  3369. var self = this;
  3370.  
  3371. C.debug('开始解析页面');
  3372.  
  3373. this.applyPatch();
  3374.  
  3375. this.applyAsyncPatch(function() {
  3376. self.preProcessDoc(callback);
  3377. });
  3378.  
  3379. return this;
  3380. },
  3381. preProcessDoc: function(callback) {
  3382. var self = this;
  3383. var endFn = function(data) {
  3384. if (data) {
  3385. var div;
  3386. if (data.content) {
  3387. div = $('<div id="content"></div>').html(data.content);
  3388. } else if (data.html) {
  3389. div = $('<div></div>').html(data.html);
  3390. }
  3391.  
  3392. self.$doc.find('body').prepend(div);
  3393. }
  3394.  
  3395. self.parse();
  3396. callback(self);
  3397. };
  3398.  
  3399. if (!this.hasContent() && this.info.getContent) {
  3400. C.log('开始 info.getContent');
  3401. this.info.getContent.call(this, this.$doc, endFn);
  3402. } else {
  3403. // 特殊处理,例如起点
  3404. var ajaxScript = this.$doc.find('.' + READER_AJAX);
  3405. if (ajaxScript.length > 0) {
  3406. var url = ajaxScript.attr('src');
  3407. if(!url) return;
  3408. var charset = ajaxScript.attr('charset') || 'utf-8';
  3409.  
  3410. C.log('Ajax 获取内容: ', url, ". charset=" + charset);
  3411.  
  3412. var reqObj = {
  3413. url: url,
  3414. method: "GET",
  3415. overrideMimeType: "text/html;charset=" + charset,
  3416. headers: {},
  3417. onload: function(res){
  3418. var text = res.responseText;
  3419. text = text.replace(/document.write(ln)?\('/, "")
  3420. .replace("');", "")
  3421. .replace(/[\n\r]+/g, '</p><p>');
  3422.  
  3423. endFn({
  3424. content: text
  3425. });
  3426. }
  3427. };
  3428.  
  3429. // Jixun: Allow post data
  3430. var postData = ajaxScript.data('post');
  3431.  
  3432. if (postData) {
  3433. reqObj.method = 'POST';
  3434. reqObj.data = $.param(postData);
  3435. reqObj.headers['Content-Type'] = 'application/x-www-form-urlencoded';
  3436. }
  3437.  
  3438. GM_xmlhttpRequest(reqObj);
  3439. } else {
  3440. endFn();
  3441. }
  3442. }
  3443. },
  3444. parse: function() {
  3445. C.group('开始获取链接');
  3446. this.getPrevUrl();
  3447. this.getIndexUrl();
  3448. this.getNextUrl();
  3449. C.groupEnd();
  3450.  
  3451. C.group('开始获取标题');
  3452. this.getTitles();
  3453. C.groupEnd();
  3454.  
  3455. this.getContent();
  3456. },
  3457.  
  3458. hasContent: function() {
  3459. var $content;
  3460.  
  3461. // var $ajaxScript = this.$doc.find('.' + READER_AJAX);
  3462. // if ($ajaxScript.length > 0) {
  3463. // return true;
  3464. // }
  3465.  
  3466. // 排除 qidian 需付费的页面
  3467. if (this.info.isVipChapter) {
  3468. if (this.info.isVipChapter(this.$doc)) {
  3469. this.isTheEnd = 'vip';
  3470. return false;
  3471. }
  3472. }
  3473.  
  3474. if(this.info.contentSelector){
  3475. $content = this.$doc.find(this.info.contentSelector);
  3476. }
  3477.  
  3478. if (!$content || !$content.length) {
  3479. // 按照顺序选取
  3480. var selectors = Rule.contentSelectors;
  3481. for(var i = 0, l = selectors.length; i < l; i++){
  3482. $content = this.$doc.find(selectors[i]);
  3483. if($content.length){
  3484. C.log("自动查找内容选择器: " + selectors[i]);
  3485. break;
  3486. }
  3487. }
  3488. }
  3489.  
  3490. this.$content = $content;
  3491. // C.debug($content);
  3492.  
  3493. return $content.size() > 0;
  3494. },
  3495. // 获取书名和章节标题
  3496. getTitles: function(){
  3497. var info = this.info,
  3498. chapterTitle,
  3499. bookTitle,
  3500. docTitle = this.$doc.find("title").text();
  3501.  
  3502. // 获取章节标题
  3503. if (info.titleReg){
  3504. var matches = docTitle.match(toRE(info.titleReg, 'i'));
  3505. if(matches && matches.length >= 2){
  3506. var titlePos = ( info.titlePos || 0 ) + 1;
  3507. var chapterPos = (titlePos == 1) ? 2 : 1;
  3508.  
  3509. bookTitle = matches[titlePos];
  3510. chapterTitle = matches[chapterPos];
  3511. }
  3512.  
  3513. C.log("TitleReg:", info.titleReg, matches);
  3514. }
  3515.  
  3516. // 如果有 titleSelector 则覆盖从 titleReg 中获取的
  3517. var tmpChapterTitle = this.getTitleFromRule(info.titleSelector);
  3518. if (tmpChapterTitle) {
  3519. chapterTitle = tmpChapterTitle;
  3520. }
  3521.  
  3522. if(!chapterTitle){
  3523. chapterTitle = this.autoGetChapterTitle(this.doc);
  3524. }
  3525. if (info.chapterTitleReplace) {
  3526. chapterTitle = chapterTitle.replace(toRE(info.chapterTitleReplace), '');
  3527. }
  3528.  
  3529. // get bookTitle
  3530. if (!bookTitle && info.bookTitleSelector) {
  3531. bookTitle = this.getTitleFromRule(info.bookTitleSelector);
  3532. }
  3533. if (!bookTitle) {
  3534. bookTitle = autoGetBookTitle(this.$doc);
  3535. bookTitle = this.replaceText(bookTitle, Rule.bookTitleReplace);
  3536. }
  3537. if (info.bookTitleReplace) {
  3538. bookTitle = bookTitle.replace(toRE(info.bookTitleReplace), '');
  3539. }
  3540.  
  3541. // 标题间增加一个空格,不准确,已注释
  3542. chapterTitle = chapterTitle
  3543. .replace(Rule.titleReplace, "")
  3544. .trim();
  3545. // .replace(/(第?\S+?[章节卷回])(.*)/, "$1 $2");
  3546.  
  3547. if (chapterTitle.startsWith(bookTitle)) {
  3548. chapterTitle = chapterTitle.replace(bookTitle, '').trim();
  3549. }
  3550.  
  3551. bookTitle = bookTitle.replace(/(?:最新章节|章节目录)$/, '');
  3552.  
  3553. docTitle = bookTitle ?
  3554. bookTitle + ' - ' + chapterTitle :
  3555. docTitle;
  3556.  
  3557. if (Setting.cn2tw) {
  3558. bookTitle = this.convert2tw(bookTitle);
  3559. chapterTitle = this.convert2tw(chapterTitle);
  3560. docTitle = this.convert2tw(docTitle);
  3561. }
  3562.  
  3563. this.bookTitle = (bookTitle || '目录').trim();
  3564. this.chapterTitle = chapterTitle;
  3565. this.docTitle = docTitle;
  3566.  
  3567. C.log("Book Title: " + this.bookTitle);
  3568. C.log("Chapter Title: " + this.chapterTitle);
  3569. C.log("Document Title: " + this.docTitle);
  3570. },
  3571. getTitleFromRule: function(selectorOrArray) {
  3572. var title = '';
  3573. if (!selectorOrArray) {
  3574. return '';
  3575. }
  3576.  
  3577. var selector,
  3578. replace;
  3579.  
  3580. if (_.isArray(selectorOrArray)) {
  3581. selector = selectorOrArray[0];
  3582. replace = selectorOrArray[1];
  3583. } else {
  3584. selector = selectorOrArray;
  3585. }
  3586.  
  3587. var $title = this.$doc.find(selector);
  3588. if (!$title.length) {
  3589. C.error('无法找到标题', selector, this.doc);
  3590. return '';
  3591. }
  3592.  
  3593. title = $title.remove().text().trim();
  3594.  
  3595. if (replace) {
  3596. title = title.replace(toRE(replace), '');
  3597. }
  3598.  
  3599. return title;
  3600. },
  3601. // 智能获取章节标题
  3602. autoGetChapterTitle: function (document) {
  3603. var
  3604. _main_selector = "h1, h2, h3",
  3605. _second_selector = "#TextTitle, #title, .ChapterName, #lbChapterName, div.h1",
  3606. _positive_regexp = Rule.titleRegExp,
  3607. // _positive_regexp = /第?\S+[章节卷回]|\d{2,4}/,
  3608. // _negative_regexp = /[上前下后][一]?[页张个篇章节步]/,
  3609. _title_remove_regexp = /最新章节|书书网/,
  3610. $doc = $(document),
  3611. _document_title = document.title || $doc.find("title").text(),
  3612. _search_document_title = ' ' + _document_title.replace(/\s+/gi, ' ') + ' ';
  3613.  
  3614. var _headings = $doc.find(_main_selector);
  3615. // 加上 second selector 并去除包含的
  3616. $doc.find(_second_selector).each(function(){
  3617. if($(this).find(_main_selector).length === 0){
  3618. _headings.push(this);
  3619. }
  3620. });
  3621.  
  3622. var possibleTitles = {},
  3623. _heading_text;
  3624.  
  3625. C.groupCollapsed('自动查找章节标题');
  3626.  
  3627. $(_headings).each(function(){
  3628. var _heading = this,
  3629. _heading_text = _heading.textContent.trim();
  3630.  
  3631. if (!_heading_text || _heading_text in possibleTitles) {
  3632. return;
  3633. }
  3634.  
  3635. C.group('开始计算 "' + _heading_text + '" 的得分');
  3636.  
  3637. // h1 为 1, h2 为 2
  3638. var
  3639. nodeNum = parseInt(_heading.nodeName.slice(1), 10) || 10,
  3640. score = 10 / nodeNum,
  3641. _heading_words = _heading_text.replace(/\s+/g, " ").split(" "),
  3642. _matched_words = "";
  3643.  
  3644. C.log("初始得分:" + score);
  3645.  
  3646. // 后面这种是特殊的判断
  3647. if (_positive_regexp.test(_heading_text) || /\d{2,4}/.test(_heading_text)) {
  3648. score += 50;
  3649. }
  3650. // if(_negative_regexp.test(_heading_text)){
  3651. // score -= 100;
  3652. // }
  3653.  
  3654. C.log("符合正则计算后得分:" + score);
  3655.  
  3656. // count words present in title
  3657. for (var j = 0, _j = _heading_words.length; j < _j; j++) {
  3658. if (_search_document_title.indexOf(_heading_words[j]) > -1) {
  3659. _matched_words += _heading_words[j] + ' ';
  3660. }
  3661. }
  3662. score += _matched_words.length * 1.5;
  3663.  
  3664. C.log("跟页面标题比较后得分:" + score);
  3665.  
  3666. var _font_size_add_score = getElemFontSize(_heading) * 1.5;
  3667. score += _font_size_add_score;
  3668.  
  3669. C.log("计算大小后得分:" + score);
  3670.  
  3671. possibleTitles[_heading_text] = score;
  3672.  
  3673. C.groupEnd();
  3674. });
  3675.  
  3676. // 找到分数最高的值
  3677. var topScoreTitle,
  3678. score_tmp = 0;
  3679. for (_heading_text in possibleTitles) {
  3680. if (possibleTitles[_heading_text] > score_tmp) {
  3681. topScoreTitle = _heading_text;
  3682. score_tmp = possibleTitles[_heading_text];
  3683. }
  3684. }
  3685.  
  3686. var curTitle = topScoreTitle;
  3687. if (!curTitle) {
  3688. curTitle = _document_title;
  3689.  
  3690. // 下面的正则从
  3691. // Firefox-Firefox浏览器论坛-卡饭论坛 - 互助分享 - 大气谦和!
  3692. // 变为
  3693. // Firefox-Firefox浏览器论坛-卡饭论坛
  3694. curTitle = curTitle.replace(/\s-\s.*/i, "")
  3695. .replace(/_[^\[\]【】]+$/, "");
  3696. curTitle = curTitle.trim();
  3697. curTitle = curTitle.replace(_title_remove_regexp, '');
  3698. }
  3699.  
  3700. curTitle = curTitle.replace(Rule.titleReplace, "");
  3701.  
  3702. C.groupEnd();
  3703.  
  3704. return curTitle;
  3705. },
  3706.  
  3707. // 获取和处理内容
  3708. getContent: function(){
  3709. var self = this;
  3710.  
  3711. this.hasContent();
  3712.  
  3713. if (!this.$content || this.$content.size() <= 0) {
  3714. // callback(this);
  3715. console.error('没有找到内容', this.$doc);
  3716. return;
  3717. }
  3718.  
  3719. this.content = this.handleContentText(this.$content.html(), this.info);
  3720. },
  3721. handleContentText: function(text, info){
  3722. if(!text) return null;
  3723.  
  3724. // 贴吧的内容处理比较耗时间
  3725. C.group('开始内容处理');
  3726. C.time('内容处理');
  3727.  
  3728. var contentHandle = (typeof(info.contentHandle) == 'undefined') ? true : info.contentHandle;
  3729.  
  3730. // 拼音字、屏蔽字修复
  3731. if(contentHandle){
  3732. text = this.replaceHtml(text, Rule.replace);
  3733. }
  3734.  
  3735. /* Turn all double br's into p's */
  3736. text = text.replace(Rule.replaceBrs, '</p>\n<p>');
  3737. text = text.replace(/<\/p><p>/g, "</p>\n<p>");
  3738.  
  3739. // GM_setClipboard(text);
  3740.  
  3741. // 规则替换
  3742. if (info.contentReplace) {
  3743. text = this.replaceText(text, info.contentReplace);
  3744. }
  3745.  
  3746. // 移除文字广告等
  3747. text = this.replaceText(text, Rule.replaceAll);
  3748.  
  3749. // 去除内容中的标题
  3750. if(this.chapterTitle && Rule.titleRegExp.test(this.chapterTitle)){
  3751. try {
  3752. var reg = toReStr(this.chapterTitle).replace(/\s+/g, '\\s*');
  3753. reg = new RegExp(reg, 'ig');
  3754. text = text.replace(reg, "");
  3755. C.log('去除内容中的标题', reg);
  3756. } catch(e) {
  3757. console.error(e);
  3758. }
  3759. }
  3760.  
  3761. if (this.bookTitle) {
  3762. var regStr = '(' + toReStr(this.bookTitle) + '\\d*章)';
  3763. text = text.replace(new RegExp(regStr, 'ig'), "");
  3764. }
  3765.  
  3766. if (Setting.cn2tw) {
  3767. text = this.convert2tw(text);
  3768. }
  3769.  
  3770. try {
  3771. text = this.contentCustomReplace(text);
  3772. } catch(ex) {
  3773. console.error('自定义替换错误', ex);
  3774. }
  3775.  
  3776. // 采用 DOM 方式进行处理
  3777. var $div = $("<div>").html(text);
  3778.  
  3779. // contentRemove
  3780. $div.find(Rule.contentRemove).remove();
  3781. if(info.contentRemove){
  3782. $div.find(info.contentRemove).remove();
  3783. }
  3784.  
  3785. // 给独立的文本加上 p
  3786. var $contents = $div.contents();
  3787. if ($contents.length === 1) { // 可能里面还包裹着一个 div
  3788. $contents = $contents.contents();
  3789. }
  3790. $contents.filter(function() {
  3791. return this.nodeType == 3 &&
  3792. this.textContent != '\n' &&
  3793. (!this.nextElementSibling || this.nextElementSibling.nodeName != 'A') &&
  3794. (!this.previousElementSibling || this.previousElementSibling.nodeName != 'A');
  3795. }).wrap('<p>');
  3796.  
  3797. // 删除无效的 p,排除对大块文本的判断
  3798. $div.find('p, h1').filter(function() {
  3799. var $this = $(this);
  3800. if ($this.find('img').size()) // 排除有图片的
  3801. return false;
  3802.  
  3803. // 有效文本(排除注释、换行符、空白)个数为 0
  3804. return $this.contents().filter(function() {
  3805. return this.nodeType != 8 &&
  3806. !this.textContent.match(/^\s*$/);
  3807. }).size() == 0;
  3808. }).remove();
  3809.  
  3810. // 把一大块的文本分段
  3811. if (Setting.split_content) {
  3812. var $p = $div.find('p'),
  3813. $newP;
  3814. if ($p.length == 0 ) {
  3815. $newP = $div;
  3816. } else if ($p.length == 1) {
  3817. $newP = $p;
  3818. }
  3819.  
  3820. if ($newP) {
  3821. $newP.replaceWith('<p>' + this.splitContent($newP.html()).join('</p>\n<p>') + '</p>');
  3822. }
  3823. }
  3824.  
  3825. if(contentHandle){
  3826. $div.filter('br').remove();
  3827.  
  3828. $div.find('*').removeAttr('style');
  3829. }
  3830.  
  3831. $div.find('p').removeAttr('class');
  3832.  
  3833. // 图片居中,所有图像?
  3834. // if(info.fixImage){
  3835. // $div.find("img").each(function(){
  3836. // this.className += " blockImage";
  3837. // });
  3838. // }
  3839.  
  3840. text = $div.html();
  3841.  
  3842. // 修复第一行可能是空的情况
  3843. text = text.replace(/(?:\s|&nbsp;)+<p>/, "<p>");
  3844.  
  3845. // 修复当行就一个字符的
  3846. text = text.replace(/<\/p><p>([。])/, "$1");
  3847.  
  3848. if(config.paragraphBlank){
  3849. text = text.replace(/<p>(?:\s|&nbsp;)+/g, "<p>")
  3850. .replace(/<p>/g, "<p>  ");
  3851. }
  3852.  
  3853. // 删除空白的、单个字符的 p
  3854. text = text.replace(Rule.removeLineRegExp, "");
  3855.  
  3856. text = this.removeDump(text);
  3857.  
  3858. C.timeEnd('内容处理');
  3859. C.groupEnd();
  3860.  
  3861. return text;
  3862. },
  3863. normalizeContent: function(html) {
  3864. html = html.replace(/<\/p><p>/g, '</p>\n<p>');
  3865.  
  3866. return html;
  3867. },
  3868. /**
  3869. * 移除内容中大块的重复。
  3870. * 例如:http://www.wangshuge.com/books/109/109265/28265316.html
  3871. *
  3872. * @param {string} html 内容
  3873. * @return {string} 处理后的内容
  3874. */
  3875. removeDump: function(html) {
  3876. html = this.normalizeContent(html);
  3877. var newContent = html;
  3878.  
  3879. var lines = html.split('\n');
  3880. var firstLine = lines[0];
  3881. // 有重复
  3882. if (firstLine.length > 10) {
  3883. // 因为 indexOf 只查找第一个
  3884. var dumpIndex = lines.slice(1).indexOf(firstLine) + 1;
  3885. if (dumpIndex >= config.dumpContentMinLength) {
  3886. var firstPart = lines.slice(0, dumpIndex).join('\n');
  3887. var restPart = lines.slice(dumpIndex).join('\n')
  3888. .replace(/^<\/p>\n/, '');
  3889. if (restPart.startsWith(firstPart)) {
  3890. newContent = restPart;
  3891. }
  3892. }
  3893. }
  3894.  
  3895. return newContent;
  3896. },
  3897. replaceHtml: function(text, replaceRule) { // replaceRule 给“自定义替换规则直接生效”用
  3898. if (!replaceRule) {
  3899. replaceRule = Rule.replace;
  3900. }
  3901.  
  3902. // 先提取出 img
  3903. var imgs = {};
  3904. var i = 0;
  3905. text = text.replace(/<(img|a)[^>]*>/g, function(img){
  3906. imgs[i] = img;
  3907. return "{" + (i++) + "}";
  3908. });
  3909.  
  3910. // 修正拼音字等
  3911. text = this.contentReplacements(text, replaceRule);
  3912.  
  3913. // 还原图片
  3914. text = $.nano(text, imgs);
  3915.  
  3916. return text;
  3917. },
  3918. contentReplacements: function (text, rule) {
  3919. if (!text) return text;
  3920.  
  3921. for (var key in rule) {
  3922. text = text.replace(toRE(key, "ig"), rule[key]);
  3923. }
  3924. return text;
  3925. },
  3926. replaceText: function(text, rule){
  3927. var self = this;
  3928. switch(true) {
  3929. case _.isRegExp(rule):
  3930. text = text.replace(rule, '');
  3931. break;
  3932. case _.isString(rule):
  3933. // 还原简写
  3934. _.each(CHAR_ALIAS, function(value, key) {
  3935. rule = rule.replace(key, value);
  3936. });
  3937. var regexp = new RegExp(rule, 'ig');
  3938. text = text.replace(regexp, '');
  3939. break;
  3940. case _.isArray(rule):
  3941. rule.forEach(function(r){
  3942. text = self.replaceText(text, r);
  3943. });
  3944. break;
  3945. case _.isObject(rule):
  3946. var key;
  3947. for(key in rule){
  3948. text = text.replace(new RegExp(key, "ig"), rule[key]);
  3949. }
  3950. break;
  3951. }
  3952. return text;
  3953. },
  3954. convert2tw: function (text) {
  3955. if (!text) return text;
  3956.  
  3957. var ii, len, str;
  3958. str = text.split("");
  3959. len = str.length;
  3960. for (ii = 0; ii < len; ii++) {
  3961. str[ii] = cn2tw[str[ii]] || str[ii];
  3962. }
  3963.  
  3964. str = str.join("");
  3965.  
  3966. return str;
  3967. },
  3968. contentCustomReplace: function (text) {
  3969. if (!text) return text;
  3970.  
  3971. for (var key in Rule.customReplace) {
  3972. text = text.replace(new RegExp(key, 'ig'), Rule.customReplace[key]);
  3973. }
  3974. return text;
  3975. },
  3976. splitContent: function (text) { // 有些章节整个都集中在一起,没有分段,这个函数用于简易分段
  3977. if (text.indexOf('。') == -1) {
  3978. return [text];
  3979. }
  3980.  
  3981. var hasMark = false,
  3982. lines = [],
  3983. charCotainer = [];
  3984.  
  3985. text.split('').forEach(function(c) {
  3986. charCotainer.push(c);
  3987.  
  3988. if (c == '“') {
  3989. hasMark = true;
  3990. } else if (c == '”') {
  3991. hasMark = false;
  3992. } else if (c == '。' && !hasMark) {
  3993. lines.push(charCotainer.join(''));
  3994. charCotainer = [];
  3995. }
  3996. });
  3997.  
  3998. return lines;
  3999. },
  4000.  
  4001. getIndexUrl: function(){
  4002. var url = '',
  4003. selector = this.info.indexSelector || this.info.indexUrl;
  4004.  
  4005. if (selector === false) {
  4006. this.indexUrl = url;
  4007. return url;
  4008. }
  4009.  
  4010. // 先尝试站点规则
  4011. if (selector && _.isFunction(selector)) {
  4012. url = selector(this.$doc);
  4013. } else if(this.info.indexSelector){
  4014. url = this.$doc.find(this.info.indexSelector);
  4015. }
  4016.  
  4017. // 再尝试通用规则
  4018. if (!url || !url.length) {
  4019. var selectors = Rule.indexSelectors;
  4020. var _indexLink;
  4021. // 按照顺序选取目录链接
  4022. for(var i = 0, l = selectors.length; i < l; i++){
  4023. _indexLink = this.$doc.find(selectors[i]);
  4024. if(_indexLink.length > 0){
  4025. url = _indexLink;
  4026. break;
  4027. }
  4028. }
  4029. }
  4030.  
  4031. if(url){
  4032. url = this.checkLinks(url);
  4033. C.log("找到目录链接: " + url);
  4034. }
  4035.  
  4036. if (!url) {
  4037. C.log("无法找到目录链接.");
  4038. }
  4039.  
  4040. this.indexUrl = url;
  4041. return url;
  4042. },
  4043. getNextUrl: function(){
  4044. var url = '',
  4045. selector = this.info.nextSelector || this.info.nextUrl;
  4046.  
  4047. if (selector === false) {
  4048. this.nextUrl = url;
  4049. return url;
  4050. }
  4051.  
  4052. // 先尝试站点规则
  4053. if (selector) {
  4054. if (_.isFunction(selector)) {
  4055. url = selector(this.$doc);
  4056. } else {
  4057. url = this.$doc.find(selector);
  4058. }
  4059.  
  4060. url = this.checkLinks(url);
  4061. }
  4062.  
  4063. // 再尝试通用规则
  4064. if (!url) {
  4065. url = this.$doc.find(Rule.nextSelector);
  4066. url = this.checkLinks(url);
  4067. }
  4068.  
  4069. if (url) {
  4070. C.log("找到下一页链接: " + url);
  4071. } else {
  4072. C.log("无法找到下一页链接");
  4073. }
  4074.  
  4075. this.nextUrl = url || '';
  4076. this.isTheEnd = !this.checkNextUrl(url);
  4077. if(this.isTheEnd){
  4078. C.log('已到达最后一页');
  4079. this.theEndColor = config.end_color;
  4080. }
  4081.  
  4082. return url;
  4083. },
  4084. // 获取上下页及目录页链接
  4085. getPrevUrl: function(){
  4086. var url = '',
  4087. selector = this.info.prevSelector || this.info.prevUrl;
  4088.  
  4089. if (selector === false) {
  4090. this.prevUrl = url;
  4091. return url;
  4092. }
  4093.  
  4094. // 先尝试站点规则
  4095. if (selector) {
  4096. if (_.isFunction(selector)) {
  4097. url = selector(this.$doc);
  4098. } else {
  4099. url = this.$doc.find(selector);
  4100. }
  4101.  
  4102. url = this.checkLinks(url);
  4103. }
  4104.  
  4105. // 再尝试通用规则
  4106. if (!url) {
  4107. url = this.$doc.find(Rule.prevSelector);
  4108. url = this.checkLinks(url);
  4109. }
  4110.  
  4111. if (url) {
  4112. C.log("找到上一页链接: " + url);
  4113. } else {
  4114. C.log("无法找到上一页链接");
  4115. }
  4116.  
  4117. this.prevUrl = url || '';
  4118. return url;
  4119. },
  4120. checkNextUrl: function(url){
  4121. if (this.info.checkSection) {
  4122. if (/\/\d+_\d+\.html$/.test(this.curPageUrl)) {
  4123. this.isSection = true;
  4124. if(url == this.indexUrl){
  4125. return false;
  4126. }else{
  4127. return true;
  4128. }
  4129. }
  4130. }
  4131.  
  4132. // 跟 include 比较
  4133. var includeUrl = this.info.includeUrl || this.getIncludeUrl();
  4134. if (!toRE(includeUrl).test(url))
  4135. return false;
  4136.  
  4137. switch(true){
  4138. case url === '':
  4139. return false
  4140. case this.info.exclude && toRE(this.info.exclude).test(url):
  4141. return false
  4142. case Rule.nextUrlIgnore.some(function(re) { return toRE(re).test(url) }):
  4143. return false
  4144. case url === this.indexUrl:
  4145. return false
  4146. case url === this.prevUrl:
  4147. return false
  4148. case url === this.curPageUrl:
  4149. return false
  4150. case Rule.nextUrlCompare.test(this.prevUrl) && !Rule.nextUrlCompare.test(url):
  4151. return false
  4152. default:
  4153. return true
  4154. }
  4155. },
  4156. getIncludeUrl: function() {
  4157. var includeUrl = this.info.url;
  4158.  
  4159. if (!includeUrl && typeof GM_info !== 'undefined') {
  4160. var locationHref = location.href;
  4161. GM_info.script.includes.some(function(includeStr) {
  4162. var iUrl = wildcardToRegExpStr(includeStr);
  4163. if (toRE(iUrl).test(locationHref)) {
  4164. includeUrl = iUrl;
  4165. return true;
  4166. }
  4167. });
  4168. }
  4169.  
  4170. this.info.includeUrl = includeUrl;
  4171. return includeUrl;
  4172. },
  4173. checkLinks: function(links){
  4174. var self = this;
  4175. var url = '';
  4176.  
  4177. if (!links) return ''
  4178.  
  4179. if (_.isString(links)) {
  4180. return this.getFullHref(links);
  4181. }
  4182.  
  4183. links && links.each(function(){
  4184. url = $(this).attr("href");
  4185. if(!url || url.indexOf("#") === 0 || url.indexOf("javascript:") === 0)
  4186. return;
  4187.  
  4188. url = self.getFullHref(this);
  4189. return false;
  4190. });
  4191.  
  4192. return url;
  4193. },
  4194. getLinkUrl: function(linkOrUrl) {
  4195. // if (linkOrUrl && )
  4196. return linkOrUrl;
  4197. },
  4198. getFullHref: function(href) {
  4199. if(!href) return '';
  4200.  
  4201. if (!_.isString(href)) {
  4202. href = href.getAttribute('href');
  4203. }
  4204.  
  4205. if (href.indexOf('http://') === 0) {
  4206. return href;
  4207. }
  4208.  
  4209. var a = this.a;
  4210. if (!a) {
  4211. this.a = a = document.createElement('a');
  4212. }
  4213. a.href = href;
  4214.  
  4215. // // 检测 host 是否和 当前页的一致
  4216. // if (a.host != this._curPageHost) {
  4217. // a.host = this._curPageHost;
  4218. // }
  4219.  
  4220. return a.href;
  4221. },
  4222. };
  4223.  
  4224. var tpl_mainCss = "@font-face {\r\n font-family: 'FontAwesome';\r\n src: url('https://cdn.bootcss.com/font-awesome/4.7.0/fonts/fontawesome-webfont.eot?v=4.7.0');\r\n src: url('https://cdn.bootcss.com/font-awesome/4.7.0/fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'), url('https://cdn.bootcss.com/font-awesome/4.7.0/fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'), url('https://cdn.bootcss.com/font-awesome/4.7.0/fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'), url('https://cdn.bootcss.com/font-awesome/4.7.0/fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'), url('https://cdn.bootcss.com/font-awesome/4.7.0/fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg');\r\n font-weight: normal;\r\n font-style: normal;\r\n }\r\n\r\nbody > a { display:none !important; }\r\n.hidden {\r\n display: none;\r\n}\r\n.quiet-mode {\r\n display: none;\r\n}\r\nbody {\r\n background: #F3F2EE;\r\n color: #1F0909;\r\n padding: 0px;\r\n margin: 0px;\r\n font-family: \"Microsoft YaHei UI\", 微软雅黑, 新宋体, 宋体, arial;\r\n}\r\na { color: #065488; }\r\na:link { text-decoration: none; }\r\n\r\n#mynovelreader-content {\r\n width: {content_width};\r\n font-size: {font_size};\r\n font-family: {font_family};\r\n line-height: {text_line_height};\r\n margin-left:auto;\r\n margin-right:auto;\r\n padding-bottom: 15px;\r\n}\r\n#mynovelreader-content img{\r\n max-width: 100%;\r\n}\r\n\r\narticle {\r\n margin-top: 55px;\r\n word-wrap: break-word;\r\n}\r\n\r\narticle h1 {\r\n clear: both;\r\n line-height: 50px;\r\n font-size: {title_font_size};\r\n font-weight: normal;\r\n margin: 25px -20px;\r\n padding: 0 20px 10px;\r\n border-bottom: 1px solid rgba(0,0,0,.25);\r\n font-weight: normal;\r\n text-transform: none;\r\n}\r\n\r\narticle li {\r\n list-style: none;\r\n}\r\n\r\n.chapter-footer-nav {\r\n text-align:center;\r\n font-size:0.9em;\r\n margin:-10px 0px 30px 0px;\r\n}\r\n#loading {\r\n color: white;\r\n text-align: center;\r\n font: 12px \"微软雅黑\", \"宋体\", \"Times New Roman\", \"Verdana\";\r\n margin-top: 20px;\r\n margin-left: auto;\r\n margin-right: auto;\r\n width: 376px;\r\n height: 32px;\r\n line-height: 32px;\r\n border-radius: 20px;\r\n border: 1px solid #666;\r\n background-color: #333;\r\n}\r\n#loading img {\r\n vertical-align: middle;\r\n}\r\n#loading a {\r\n color: white;\r\n}\r\n#preferencesBtn{\r\n position: fixed;\r\n top: 10px;\r\n right: 10px;\r\n z-index: 1597;\r\n}\r\n\r\n#alert {\r\n position: fixed;\r\n z-index: 100;\r\n float: auto;\r\n width: auto;\r\n height: auto;\r\n top: 10px;\r\n left: 500px;\r\n background: rgba(215, 240, 253, 0.65);\r\n color: #2d7091;\r\n border: 1px solid rgba(45,112,145,0.3);\r\n border-radius: 4px;\r\n}\r\n#alert p {\r\n font-size: 15px;\r\n margin: 6px;\r\n}\r\n\r\n#message {\r\n position: fixed;\r\n z-index: 1010;\r\n width: auto;\r\n height: auto;\r\n top: 10px;\r\n left: 500px;\r\n\r\n padding: 8px 16px;\r\n border-radius: 4px;\r\n box-shadow: 0 2px 8px rgba(0,0,0,.2);\r\n background: #fff;\r\n display: inline-block;\r\n pointer-events: all;\r\n\r\n font-size: 12px;\r\n}\r\n#message .fa-spinner {\r\n font-size: 13px;\r\n margin-right: 4px;\r\n}\r\n#message p {\r\n margin: 0;\r\n}\r\n\r\nimg.blockImage {clear: both;float: none;display: block;margin-left: auto;margin-right: auto;}\r\n\r\n#menu-bar {\r\n border: solid rgba(0, 100, 255, .9);\r\n border-width: 3px 2px 3px 0px;\r\n position: fixed;\r\n left: 0px;\r\n top: 40%;\r\n height: 100px;\r\n width: 2px;\r\n z-index: 199;\r\n {menu-bar-hidden}\r\n}\r\n#menu-bar {\r\n top: 0px;\r\n height: 100%;\r\n width: 1px;\r\n background: transparent;\r\n border: none;\r\n}\r\n#menu {\r\n position: fixed;\r\n top: 0;\r\n bottom: 0;\r\n left: 0;\r\n z-index: 100;\r\n width: 270px;\r\n max-width: 100%;\r\n background: #333;\r\n overflow-y: auto;\r\n}\r\n#menu:after {\r\n content: \"\";\r\n display: block;\r\n position: absolute;\r\n top: 46px;\r\n bottom: 0;\r\n right: 0;\r\n width: 1px;\r\n background: rgba(0,0,0,0.6);\r\n box-shadow: 0 0 5px 2px rgba(0,0,0,0.6);\r\n}\r\n#header{\r\n color: #777;\r\n margin-top: 0;\r\n border-top: 1px solid rgba(0,0,0,0.3);\r\n background: #404040;\r\n box-shadow: inset 0 1px 0 rgba(255,255,255,0.05);\r\n text-shadow: 0 1px 0 rgba(0,0,0,0.5);\r\n padding: 10px 12px;\r\n text-transform: uppercase;\r\n font-weight: bold;\r\n font-size: 20px;\r\n}\r\n#header a {\r\n color: #777777;\r\n}\r\n#divider {\r\n position: relative;\r\n z-index: 300;\r\n border-top: 1px solid rgba(255,255,255,0.01);\r\n border-bottom: 1px solid rgba(0,0,0,0.3);\r\n margin: 0;\r\n height: 4px;\r\n background: rgba(0,0,0,0.2);\r\n box-shadow: 0 1px 0 rgba(255,255,255,0.05), inset 0 1px 3px rgba(0,0,0,0.3);\r\n}\r\n#chapter-list {\r\n position: relative;\r\n bottom: 0;\r\n left: 0;\r\n right: 0;\r\n z-index: 200;\r\n margin: 0;\r\n padding: 0;\r\n cursor: pointer;\r\n list-style: none;\r\n overflow-y: auto;\r\n}\r\n.chapter {\r\n list-style: none;\r\n}\r\n.chapter:last-child {\r\n border-bottom: 1px solid rgba(0,0,0,0.3);\r\n box-shadow: 0 1px 0 rgba(255,255,255,0.05);\r\n}\r\n.chapter div {\r\n color: #ccc;\r\n font-size: 15px;\r\n padding: 8px 20px;\r\n border-top: 1px solid rgba(0,0,0,0.3);\r\n box-shadow: inset 0 1px 0 rgba(255,255,255,0.05);\r\n text-shadow: 0 1px 0 rgba(0,0,0,0.5);\r\n display: block;\r\n text-decoration: none;\r\n text-overflow: ellipsis;\r\n overflow: hidden;\r\n white-space: nowrap;\r\n cursor: pointer;\r\n}\r\n.chapter div:before {\r\n content: \"\\f105\";\r\n width: 20px;\r\n margin-left: -10px;\r\n float: left;\r\n font-family: \"FontAwesome\" !important;\r\n text-align: center;\r\n}\r\n.chapter div:hover {\r\n background: #404040;\r\n color: #fff;\r\n outline: 0;\r\n}\r\n.chapter.active div {\r\n background: #1a1a1a;\r\n color: #fff;\r\n font-size: 16px;\r\n box-shadow: inset 0 1px 3px rgba(0,0,0,0.3);\r\n}\r\n::-webkit-scrollbar {\r\n height: 9px !important;\r\n width: 9px !important;\r\n}\r\n::-webkit-scrollbar-thumb {\r\n background-color: #7D7D7D !important;\r\n border-radius: 3px !important;\r\n}\r\n::-webkit-scrollbar-track-piece {\r\n background-color: rgba(0,0,0,.25) !important;\r\n}\r\n";
  4225.  
  4226. var tpl_preferencesHTML = "<form id=\"preferences\" name=\"preferences\">\n <div id=\"setting_table1\">\n <span id=\"top-buttons\">\n <input title=\"部分选项需要刷新页面才能生效\" id=\"save_button\" value=\"√ 确认\" type=\"button\">\n <input title=\"取消本次设定,所有选项还原\" id=\"close_button\" value=\"X 取消\" type=\"button\">\n </span>\n <div class=\"form-row\">\n <label>\n 界面语言<select id=\"lang\">\n </select>\n </label>\n <label title=\"将小说网页文本转换为繁体。\\n\\n注意:内置的繁简转换表,只收录了简单的单字转换,启用本功能后,如有错误转换的情形,请利用脚本的自订字词取代规则来修正。\\n例如:「千里之外」,会错误转换成「千里之外」,你可以加入规则「千里之外=千里之外」来自行修正。\">\n <input type=\"checkbox\" id=\"enable-cn2tw\" name=\"enable-cn2tw\"/>网页:转繁体\n </label>\n <label id=\"quietMode\" class=\"right\" title=\"隐藏其他,只保留正文,适用于全屏状态下\">\n <input class=\"key\" type=\"button\" id=\"quietModeKey\"/>安静模式\n </label>\n </div>\n <div class=\"form-row\">\n <label title=\"不影响 booklink.me 的启用\">\n <input type=\"checkbox\" id=\"disable-auto-launch\" name=\"disable-auto-launch\"/>强制手动启用\n </label>\n <label title=\"booklink.me 点击的网站强制启用\">\n <input type=\"checkbox\" id=\"booklink-enable\" name=\"booklink-enable\"/>booklink 自动启用\n </label>\n <label>\n <input type=\"checkbox\" id=\"debug\" name=\"debug\"/>调试模式\n </label>\n <a href=\"https://greasyfork.org/scripts/292-my-novel-reader/feedback\" target=\"_blank\">反馈地址</a>\n </div>\n <div class=\"form-row\">\n <label title=\"图片章节用夜间模式没法看,这个选项在启动时会自动切换到缺省皮肤\">\n <input type=\"checkbox\" id=\"pic-nightmode-check\" name=\"pic-nightmode-check\"/>\n 夜间模式的图片章节检测\n </label>\n <label>\n <input type=\"checkbox\" id=\"copyCurTitle\"/>\n 打开目录复制当前标题\n </label>\n </div>\n <div class=\"form-row\">\n <label title=\"通过快捷键切换\">\n <input type=\"checkbox\" id=\"hide-menu-list\"/>隐藏左侧章节列表\n </label>\n <label>\n <input type=\"checkbox\" id=\"hide-footer-nav\"/>隐藏底部导航栏\n </label>\n <label class=\"right\" title=\"导出之后的所有章节\">\n <input type=\"button\" id=\"saveAsTxt\" value=\"存为 txt(测试)\" />\n <input type=\"button\" id=\"speech\" value=\"朗读\" />\n </label>\n </div>\n <div class=\"form-row\">\n <label>\n 左侧导航栏切换快捷键:\n </label>\n <input class=\"key\" type=\"button\" id=\"setHideMenuListKey\" />\n <label title=\"通过快捷键切换或在 Greasemonkey 用户脚本命令处打开设置窗口\">\n <input type=\"checkbox\" id=\"hide-preferences-button\"/>隐藏设置按钮\n </label>\n <input class=\"key\" type=\"button\" id=\"openPreferencesKey\"/>\n </div>\n <div class=\"form-row\">\n <label>\n 打开朗读快捷键:\n </label>\n <input class=\"key\" type=\"button\" id=\"setOpenSpeechKey\" />\n </div>\n <div class=\"form-row\">\n <label>\n 距离底部\n <input type=\"textbox\" id=\"remain-height\" name=\"remain-height\" size=\"5\"/>\n px 加载下一页\n </label>\n <label>\n <input type=\"checkbox\" id=\"add-nextpage-to-history\"/>添加下一页到历史记录\n </label>\n <label>\n <input type=\"checkbox\" id=\"enable-dblclick-pause\"/>双击暂停翻页\n </label>\n </div>\n <div class=\"form-row\">\n <label>\n <select id=\"skin\">\n </select>\n </label>\n <label>\n 字体\n <input type=\"textbox\" id=\"font-family\" style=\"min-width:200px;\"/>\n </label>\n <br/><br/>\n <label>\n 字体大小\n <input type=\"textbox\" id=\"font-size\" name=\"font-size\" size=\"6\"/>\n </label>\n <label>\n 行高\n <input type=\"textbox\" id=\"text_line_height\" size=\"6\"/>\n </label>\n <label>\n 行宽\n <input type=\"textbox\" id=\"content_width\" size=\"6\"/>\n </label>\n </div>\n <div class=\"form-row\">\n <label title=\"把一大块未分段的内容文本按照句号分段\">\n <input type=\"checkbox\" id=\"split_content\"/>对一坨内容进行强制分段\n </label>\n <label>\n <input type=\"checkbox\" id=\"scroll_animate\"/>章节直达滚动效果\n </label>\n </div>\n <div class=\"form-row\">\n <div class=\"prefs_title\">自定义样式</div>\n <textarea id=\"extra_css\" class=\"prefs_textarea\" placeholder=\"自定义样式\"></textarea>\n </div>\n </div>\n <div id=\"setting_table2\">\n <div class=\"form-row\" title=\"详见脚本代码的 Rule.specialSite\">\n <div class=\"prefs_title\">自定义站点规则</div>\n <textarea id=\"custom_siteinfo\" class=\"prefs_textarea\" placeholder=\"自定义站点规则\" />\n </div>\n <div class=\"form-row\" title=\"一行一个,每行的第一个 = 为分隔符。\\n保存后生效\">\n <div class=\"prefs_title\">自定义替换规则</div>\n <textarea id=\"custom_replace_rules\" class=\"prefs_textarea\" placeholder=\"b[āà]ng=棒\" />\n </div>\n </div>\n</form>";
  4227.  
  4228. var tpl_preferencesCSS = ".body {\r\n color:#333;\r\n margin: 0 auto;\r\n background: white;\r\n padding: 10px;\r\n height: 420px;\r\n overflow-y: auto;\r\n }\r\n #top-buttons {\r\n background: none repeat scroll 0% 0% rgb(255, 255, 255);\r\n display: block;\r\n position: absolute;\r\n top: -35px;\r\n border-right: 12px solid rgb(224, 224, 224);\r\n border-top: 12px solid rgb(224, 224, 224);\r\n border-left: 12px solid rgb(224, 224, 224);\r\n text-align: center;\r\n }\r\n input {\r\n font-size: 12px;\r\n margin-right: 3px;\r\n vertical-align: middle;\r\n }\r\n .form-row {\r\n overflow: hidden;\r\n padding: 8px 12px;\r\n margin-top: 3px;\r\n font-size: 11px;\r\n }\r\n .form-row label {\r\n padding-right: 10px;\r\n }\r\n .form-row input {\r\n vertical-align: middle;\r\n margin-top: 0px;\r\n }\r\n textarea, .form-row input {\r\n padding: 2px 4px;\r\n border: 1px solid #e5e5e5;\r\n background: #fff;\r\n border-radius: 4px;\r\n color: #666;\r\n -webkit-transition: all linear .2s;\r\n transition: all linear .2s;\r\n }\r\n textarea {\r\n width: 100%;\r\n overflow: auto;\r\n vertical-align: top;\r\n }\r\n textarea:focus, input:focus {\r\n border-color: #99baca;\r\n outline: 0;\r\n background: #f5fbfe;\r\n color: #666;\r\n }\r\n .prefs_title {\r\n font-size: 12px;\r\n font-weight: bold;\r\n }\r\n .prefs_textarea {\r\n font-size: 12px;\r\n margin-top: 5px;\r\n height: 100px;\r\n }\r\n .right {\r\n float: right;\r\n }";
  4229.  
  4230. var Res = {
  4231. CSS_MAIN: tpl_mainCss,
  4232.  
  4233. preferencesHTML: tpl_preferencesHTML
  4234. .uiTrans().replace(/\\n/g, '\n'),
  4235.  
  4236. preferencesCSS: tpl_preferencesCSS,
  4237. };
  4238.  
  4239. var tpl_mainHtml = "<div id=\"container\">\r\n <div id=\"menu-bar\" title=\"点击显示隐藏章节列表\"></div>\r\n <div id=\"menu\">\r\n <div id=\"header\" title=\"打开目录\">\r\n <a href=\"{indexUrl}\" target=\"_blank\">{bookTitle}</a>\r\n </div>\r\n <div id=\"divider\"></div>\r\n <ul id=\"chapter-list\" title=\"左键滚动,中键打开链接(无阅读模式)\">\r\n </ul>\r\n </div>\r\n <div id=\"mynovelreader-content\"></div>\r\n <div id=\"loading\" style=\"display:none\"></div>\r\n <div id=\"preferencesBtn\">\r\n <img style=\"width:16px\" src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAABwklEQVRIibVVzWrCQBAeQk/bdk+bm0aWDQEPHtwVahdavLU9aw6KAQ+SQ86Sa19Aqu0T9NafSw8ttOgr1CewUB9CBL3Yy26x1qRp0A8GhsnO9yUzmxmAhKjX68cAMAeAufK3C875FQAsAWCp/O3CsqyhFlB+Oti2/cAYewrD8FDHarXahWEYUy1gGMbUdd1z/TwMw0PG2JNt2/ex5IyxR02CEJpIKbuEkJGOrRshZCSl7CKEJjrGGHuIFMjlcs9RZElNcWxGEAQHGONxWnKM8TgIgoPYMkkpL9MKqNx4xNX8LyOEvMeSq5uxMZlz3vN9v+D7foFz3os6V61Wz36QNhqNUyHENaV0CACLTUnFYvF6/WVUbJPIglI6FELctFqtMiT59Ha7TdcFVCxJ6XYs0Gw2T1SJBlsq0ZxSOhBC3Hied/QjSTUoqsn9lSb3o879avI61FXbzTUFACiXy7v70Tqdzj7G+COtwJ+jIpPJvKYl12ZZ1kucwJs+iBD6lFJ2TdOMHB2mab7/a1xXKpW9fD5/6zjO3erCcV33PMnCcRwnfuHEYXVlZrPZQWqiKJRKpe8Bt5Ol73leCQBmADBTfiJ8AebTYCRbI3BUAAAAAElFTkSuQmCC\"/>\r\n </div>\r\n <div id=\"alert\" style=\"display: none;\">\r\n <p id=\"App-notice\"></p>\r\n </div>\r\n\r\n <div id=\"app\">\r\n\r\n </div>\r\n</div>";
  4240.  
  4241. let $messageDiv;
  4242. let _messageTimeId;
  4243.  
  4244. function notice(html, duration, noticeType, onClose) {
  4245. if (typeof duration === 'undefined')
  4246. duration = 2000;
  4247.  
  4248. var closeMessage = function() {
  4249. $messageDiv.remove();
  4250. $messageDiv = null;
  4251.  
  4252. if (typeof onClose === 'function') {
  4253. onClose();
  4254. }
  4255. };
  4256.  
  4257. if (!$messageDiv) {
  4258. var iconHtml = '';
  4259. if (noticeType === 'loading') {
  4260. iconHtml = '<i class="fa fa-spinner fa-pulse fa-3x fa-fw"></i>';
  4261. }
  4262.  
  4263. $messageDiv = $('<div id="message" class="noRemove">' + iconHtml + '<span id="content"></span></div>')
  4264. .appendTo('body');
  4265.  
  4266. if (duration == 0) {
  4267. $messageDiv.on('click', closeMessage);
  4268. }
  4269. }
  4270.  
  4271. $messageDiv.find('#content').html(html);
  4272.  
  4273. if (duration > 0) {
  4274. clearTimeout(_messageTimeId);
  4275. _messageTimeId = setTimeout(closeMessage, duration);
  4276. }
  4277. }
  4278.  
  4279. function loading(html, duration, onClose) {
  4280. notice(html, duration, 'loading', onClose);
  4281. }
  4282.  
  4283. function saveAs(data, filename) {
  4284. if(!filename) filename = 'console.json';
  4285.  
  4286. if (typeof data == 'object') {
  4287. data = JSON.stringify(data, undefined, 4);
  4288. }
  4289.  
  4290. var blob = new Blob([data], { type: 'application/octet-stream' });
  4291. var blobUrl = window.URL.createObjectURL(blob);
  4292. var tmpLink = document.createElement('a');
  4293. tmpLink.href = blobUrl;
  4294. tmpLink.style.display = 'none';
  4295. tmpLink.setAttribute('download', filename);
  4296. tmpLink.setAttribute('target', '_blank');
  4297. document.body.appendChild(tmpLink);
  4298.  
  4299. tmpLink.click();
  4300. document.body.removeChild(tmpLink);
  4301. window.URL.revokeObjectURL(blobUrl);
  4302. }
  4303.  
  4304. /**
  4305. * 获取 substring 在 string 所有位置的数组
  4306. *
  4307. * @param {string} substring
  4308. * @param {string} string
  4309. * @returns {number[]}
  4310. */
  4311. function locations(substring, string){
  4312. var a=[],i=-1;
  4313. while((i=string.indexOf(substring,i+1)) >= 0) a.push(i);
  4314. return a;
  4315. }
  4316.  
  4317. /**
  4318. * 22000 毫秒 => 00:00:02
  4319. *
  4320. * @param {number} distanceMillis
  4321. * @returns {string}
  4322. */
  4323. function formatMillisencod(distanceMillis) {
  4324. var sec_num = parseInt(Math.abs(distanceMillis) / 1000, 10);
  4325. var hours = Math.floor(sec_num / 3600);
  4326. var minutes = Math.floor((sec_num - (hours * 3600)) / 60);
  4327. var seconds = sec_num - (hours * 3600) - (minutes * 60);
  4328. if (hours < 10) {
  4329. hours = "0" + hours;
  4330. }
  4331. if (minutes < 10) {
  4332. minutes = "0" + minutes;
  4333. }
  4334. if (seconds < 10) {
  4335. seconds = "0" + seconds;
  4336. }
  4337. return hours + ':' + minutes + ':' + seconds;
  4338. }
  4339.  
  4340. /**
  4341. * GM_xmlhttpRequest Promise 版
  4342. *
  4343. * @export
  4344. * @param {string} url
  4345. * @param {object} [opt={}]
  4346. * @returns {Promise<string>}
  4347. */
  4348.  
  4349. /**
  4350. * 根据 xpath 查找元素
  4351. *
  4352. * @export
  4353. * @param {string} aXPath
  4354. * @param {Node} aContext
  4355. * @returns
  4356. */
  4357.  
  4358. function delay(ms) {
  4359. return new Promise((resolve) => {
  4360. setTimeout(resolve, ms);
  4361. })
  4362. }
  4363.  
  4364. function cnNum2ArabNum(cn){
  4365. var arab, parts, cnChars = '零一二三四五六七八九';
  4366.  
  4367. if (!cn) {
  4368. return 0
  4369. }
  4370.  
  4371. if (cn.indexOf('亿') !== -1){
  4372. parts = cn.split('亿');
  4373. return cnNum2ArabNum(parts[0]) * 1e8 + cnNum2ArabNum(parts[1])
  4374. }
  4375.  
  4376. if (cn.indexOf('万') !== -1){
  4377. parts = cn.split('万');
  4378. return cnNum2ArabNum(parts[0]) * 1e4 + cnNum2ArabNum(parts[1])
  4379. }
  4380.  
  4381. if (cn.indexOf('十') === 0){
  4382. cn = '一' + cn;
  4383. }
  4384.  
  4385. arab = cn
  4386. .replace(/[零一二三四五六七八九]/g, function (a) {
  4387. return '+' + cnChars.indexOf(a)
  4388. })
  4389. .replace(/(十|百|千)/g, function(a, b){
  4390. return '*' + (
  4391. b == '十' ? 1e1 :
  4392. b == '百' ? 1e2 : 1e3
  4393. )
  4394. });
  4395.  
  4396. return (new Function('return ' + arab))()
  4397. }
  4398.  
  4399. function getNumFromChapterTitle(title) {
  4400. if (!title) return;
  4401.  
  4402. var m = title.match(/第(\d+)章|^(\d+)、/);
  4403. if (m) {
  4404. return parseInt(m[1], 10)
  4405. }
  4406.  
  4407. // 第二十二章
  4408. m = title.match(/(?:第|^)([一二两三四五六七八九十○零百千万亿\d]+){1,6}章/);
  4409. if (m) {
  4410. return cnNum2ArabNum(m[1])
  4411. }
  4412.  
  4413. // 九十二 休想套路我
  4414. m = title.match(/^([一二两三四五六七八九十○零百千万亿\d]+){1,6} /);
  4415. if (m) {
  4416. return cnNum2ArabNum(m[1])
  4417. }
  4418. }
  4419.  
  4420. const chapters = [];
  4421.  
  4422. const fileName = {
  4423. bookTitle: '',
  4424. ext: '.txt',
  4425. start: 0,
  4426. end: 0,
  4427.  
  4428. setBookTitle(bookTitle) {
  4429. this.bookTitle = bookTitle;
  4430. },
  4431. setStart(chapterTitle) {
  4432. let num = getNumFromChapterTitle(chapterTitle);
  4433. if (num) {
  4434. this.start = num;
  4435. }
  4436. },
  4437. setEnd(chapterTitle) {
  4438. let num = getNumFromChapterTitle(chapterTitle);
  4439. if (num) {
  4440. this.end = num;
  4441. }
  4442. },
  4443.  
  4444. toString() {
  4445. let start = this.start || '';
  4446. let end = this.end || '';
  4447. let count = chapters.length;
  4448.  
  4449. return `${this.bookTitle || '未知名称'}(${start} - ${end},共${count}章)${this.ext}`
  4450. }
  4451. };
  4452.  
  4453. function toTxt(parser) {
  4454. var html = $.nano('{chapterTitle}\n\n{contentTxt}', parser);
  4455. chapters.push(html);
  4456.  
  4457. var msg = '已下载 ' + chapters.length + ' 章,' +
  4458. (parser.chapterTitle || '');
  4459.  
  4460. loading(msg, 0);
  4461. }
  4462.  
  4463. function finish(parser) {
  4464. var allTxt = chapters.join('\n\n');
  4465. if (isWindows) {
  4466. allTxt = allTxt.replace(/\n/g, '\r\n');
  4467. }
  4468.  
  4469. fileName.setEnd(parser.chapterTitle);
  4470.  
  4471. saveAs(allTxt, fileName.toString());
  4472. }
  4473.  
  4474. function getOnePage(parser, nextUrl, endFn) {
  4475. var isEnd = false;
  4476. if (parser) {
  4477. toTxt(parser);
  4478. nextUrl = parser.nextUrl;
  4479. isEnd = parser.isTheEnd;
  4480. }
  4481.  
  4482. if (!nextUrl || isEnd) {
  4483. console.log('全部获取完毕');
  4484. finish(parser);
  4485. if (typeof endFn == 'functiton') {
  4486. endFn();
  4487. }
  4488. return;
  4489. }
  4490.  
  4491. if (App.site.useiframe) {
  4492. // App.iframeRequest(nextUrl);
  4493. return;
  4494. }
  4495.  
  4496. setTimeout(function() {
  4497. console.log('[存为txt]正在获取:', nextUrl);
  4498. App.httpRequest(nextUrl, function(doc) {
  4499. if (doc) {
  4500. var par = new Parser(App.site, doc, nextUrl);
  4501. par.getAll(getOnePage);
  4502. } else {
  4503. console.error('超时或连接出错');
  4504. finish();
  4505. endFn();
  4506. }
  4507. });
  4508. }, config.download_delay);
  4509. }
  4510.  
  4511. function run(cachedParsers=[], endFn) {
  4512. console.log(`[存为txt]每章下载延时 ${config.download_delay} 毫秒`);
  4513.  
  4514. cachedParsers.forEach(toTxt);
  4515.  
  4516. var firstParser = cachedParsers[0];
  4517. fileName.setBookTitle(firstParser.bookTitle);
  4518. fileName.setStart(firstParser.chapterTitle);
  4519.  
  4520. var lastParser = cachedParsers[cachedParsers.length - 1];
  4521. getOnePage(null, lastParser.nextUrl, endFn);
  4522. }
  4523.  
  4524. __$styleInject(".speech {\n position: fixed;\n z-index: 100;\n background-color: white;\n top: 10px;\n right: 35px;\n}\n");
  4525.  
  4526. const bus = new Vue();
  4527.  
  4528. // 显示 语音朗读 对话框
  4529. const SHOW_SPEECH = 'show-speech';
  4530.  
  4531. const APPEND_NEXT_PAGE = 'appended_next_page';
  4532.  
  4533. __$styleInject(".speech .close-btn {\n position: absolute;\n top: 0;\n right: 0;\n}\n.speech .loader {\n text-align: center;\n}\n.speech .auto-stop-input {\n width: 30px;\n}\n.speech .tips {\n font-size: 0.8em;\n}\n");
  4534.  
  4535. __$styleInject("/*.v-spinner\n{\n margin: 100px auto;\n text-align: center;\n}\n*/\n@-webkit-keyframes v-pulseStretchDelay {\n 0%,\n 80% {\n -webkit-transform: scale(1);\n transform: scale(1);\n -webkit-opacity: 1;\n opacity: 1;\n }\n 45% {\n -webkit-transform: scale(0.1);\n transform: scale(0.1);\n -webkit-opacity: 0.7;\n opacity: 0.7;\n }\n}\n@keyframes v-pulseStretchDelay {\n 0%,\n 80% {\n -webkit-transform: scale(1);\n transform: scale(1);\n -webkit-opacity: 1;\n opacity: 1;\n }\n 45% {\n -webkit-transform: scale(0.1);\n transform: scale(0.1);\n -webkit-opacity: 0.7;\n opacity: 0.7;\n }\n}\n");
  4536.  
  4537. var PulseLoader = {
  4538. render: function(){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{directives:[{name:"show",rawName:"v-show",value:(_vm.loading),expression:"loading"}],staticClass:"v-spinner"},[_c('div',{staticClass:"v-pulse v-pulse1",style:([_vm.spinnerStyle,_vm.spinnerDelay1])}),_c('div',{staticClass:"v-pulse v-pulse2",style:([_vm.spinnerStyle,_vm.spinnerDelay2])}),_c('div',{staticClass:"v-pulse v-pulse3",style:([_vm.spinnerStyle,_vm.spinnerDelay3])})])},
  4539. staticRenderFns: [],
  4540.  
  4541. name: 'PulseLoader',
  4542. props: {
  4543. loading: {
  4544. type: Boolean,
  4545. default: true
  4546. },
  4547. color: {
  4548. type: String,
  4549. default: '#5dc596'
  4550. },
  4551. size: {
  4552. type: String,
  4553. default: '15px'
  4554. },
  4555. margin: {
  4556. type: String,
  4557. default: '2px'
  4558. },
  4559. radius: {
  4560. type: String,
  4561. default: '100%'
  4562. }
  4563. },
  4564. data () {
  4565. return {
  4566. spinnerStyle: {
  4567. backgroundColor: this.color,
  4568. width: this.size,
  4569. height: this.size,
  4570. margin: this.margin,
  4571. borderRadius: this.radius,
  4572. display: 'inline-block',
  4573. animationName: 'v-pulseStretchDelay',
  4574. animationDuration: '0.75s',
  4575. animationIterationCount: 'infinite',
  4576. animationTimingFunction: 'cubic-bezier(.2,.68,.18,1.08)',
  4577. animationFillMode: 'both'
  4578. },
  4579. spinnerDelay1: {
  4580. animationDelay: '0.12s'
  4581. },
  4582. spinnerDelay2: {
  4583. animationDelay: '0.24s'
  4584. },
  4585. spinnerDelay3: {
  4586. animationDelay: '0.36s'
  4587. }
  4588. }
  4589. }
  4590. };
  4591.  
  4592. const STATE = {
  4593. playing: 1,
  4594. pausing: 2,
  4595. stoping: 0,
  4596. };
  4597.  
  4598. var Speech = {
  4599. render: function(){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:"speech"},[(_vm.playState == _vm.STATE.playing)?_c('span',[_c('button',{on:{"click":_vm.pause}},[_vm._v("暂停朗读")]),_vm._v(" "),_c('button',{on:{"click":_vm.stop}},[_vm._v("停止朗读")])]):_c('span',[(_vm.playState == _vm.STATE.stoping)?_c('button',{on:{"click":_vm.start}},[_vm._v("开始朗读")]):_vm._e(),_vm._v(" "),(_vm.playState == _vm.STATE.pausing)?_c('button',{on:{"click":_vm.resume}},[_vm._v("继续朗读")]):_vm._e(),_vm._v(" "),(_vm.elapsedTime)?_c('span',[_vm._v("已朗读 "+_vm._s(_vm.formatMillisencod(_vm.elapsedTime)))]):_c('span',{staticClass:"tips"},[_vm._v("Tips:可从选择文本处开始朗读")]),_vm._v(" "),_c('button',{staticClass:"close-btn",on:{"click":_vm.closeSpeech}},[_vm._v("X")])]),_vm._v(" "),(_vm.playState == _vm.STATE.playing)?_c('div',{staticClass:"loader"},[_c('pulse-loader')],1):_c('div',[_c('div',[_c('label',[_c('input',{directives:[{name:"model",rawName:"v-model",value:(_vm.autoStop),expression:"autoStop"}],attrs:{"type":"radio","value":"time"},domProps:{"checked":_vm._q(_vm.autoStop,"time")},on:{"__c":function($event){_vm.autoStop="time";}}}),_vm._v("\n 定时朗读:\n "),_c('input',{directives:[{name:"model",rawName:"v-model",value:(_vm.autoStopTime),expression:"autoStopTime"}],staticClass:"auto-stop-input",attrs:{"type":"text"},domProps:{"value":(_vm.autoStopTime)},on:{"input":function($event){if($event.target.composing){ return; }_vm.autoStopTime=$event.target.value;}}}),_vm._v(" "),_c('select',{directives:[{name:"model",rawName:"v-model",value:(_vm.autoStopTimeUnit),expression:"autoStopTimeUnit"}],on:{"change":function($event){var $$selectedVal = Array.prototype.filter.call($event.target.options,function(o){return o.selected}).map(function(o){var val = "_value" in o ? o._value : o.value;return val}); _vm.autoStopTimeUnit=$event.target.multiple ? $$selectedVal : $$selectedVal[0];}}},[_c('option',{attrs:{"value":"minute"}},[_vm._v("分钟")]),_vm._v(" "),_c('option',{attrs:{"value":"hour"}},[_vm._v("小时")])]),_vm._v("\n 后停止\n ")]),_c('br'),_vm._v(" "),_c('label',[_c('input',{directives:[{name:"model",rawName:"v-model",value:(_vm.autoStop),expression:"autoStop"}],attrs:{"type":"radio","value":"chapter"},domProps:{"checked":_vm._q(_vm.autoStop,"chapter")},on:{"__c":function($event){_vm.autoStop="chapter";}}}),_vm._v("\n 定章朗读:\n "),_c('input',{directives:[{name:"model",rawName:"v-model",value:(_vm.autoStopChapter),expression:"autoStopChapter"}],staticClass:"auto-stop-input",attrs:{"type":"text"},domProps:{"value":(_vm.autoStopChapter)},on:{"input":function($event){if($event.target.composing){ return; }_vm.autoStopChapter=$event.target.value;}}}),_vm._v("章后停止\n ")]),_c('br'),_vm._v(" "),_c('label',[_c('input',{directives:[{name:"model",rawName:"v-model",value:(_vm.autoStop),expression:"autoStop"}],attrs:{"type":"radio","value":""},domProps:{"checked":_vm._q(_vm.autoStop,"")},on:{"__c":function($event){_vm.autoStop="";}}}),_vm._v("一直朗读")])]),_vm._v(" "),_c('div',[_c('label',{attrs:{"for":"speech-dialog-rate"}},[_vm._v("语速")]),_vm._v(" "),_c('input',{directives:[{name:"model",rawName:"v-model",value:(_vm.rate),expression:"rate"}],attrs:{"type":"range","min":"0.5","max":"2","value":"1","step":"0.1","id":"speech-dialog-rate"},domProps:{"value":(_vm.rate)},on:{"__r":function($event){_vm.rate=$event.target.value;}}}),_vm._v(" "),_c('span',{staticClass:"rate-value"},[_vm._v(_vm._s(_vm.rate))])]),_vm._v(" "),_c('div',[_c('label',{attrs:{"for":"speech-dialog-pitch"}},[_vm._v("音高")]),_vm._v(" "),_c('input',{directives:[{name:"model",rawName:"v-model",value:(_vm.pitch),expression:"pitch"}],attrs:{"type":"range","min":"0","max":"2","value":"1","step":"0.1","id":"speech-dialog-pitch"},domProps:{"value":(_vm.pitch)},on:{"__r":function($event){_vm.pitch=$event.target.value;}}}),_vm._v(" "),_c('span',{staticClass:"pitch-value"},[_vm._v(_vm._s(_vm.pitch))])]),_vm._v(" "),_c('div',[_c('select',{directives:[{name:"model",rawName:"v-model",value:(_vm.selectedVoice),expression:"selectedVoice"}],staticClass:"voices",on:{"change":function($event){var $$selectedVal = Array.prototype.filter.call($event.target.options,function(o){return o.selected}).map(function(o){var val = "_value" in o ? o._value : o.value;return val}); _vm.selectedVoice=$event.target.multiple ? $$selectedVal : $$selectedVal[0];}}},_vm._l((_vm.voiceList),function(voice,index){return _c('option',{key:index,domProps:{"value":index}},[_vm._v("\n "+_vm._s(voice.name)+" "+_vm._s(voice.lang)+"\n ")])}))])])])},
  4600. staticRenderFns: [],
  4601. name: 'speech',
  4602. data() {
  4603. return {
  4604. text: '',
  4605. // 播放状态
  4606. STATE,
  4607. playState: STATE.stoping, // 监控朗读的状态
  4608. isPlaying: false, // 按钮的状态
  4609. elapsedTime: 0,
  4610.  
  4611. voiceList: [],
  4612. selectedVoice: 0,
  4613. rate: 1,
  4614. pitch: 1,
  4615.  
  4616. autoStop: '',
  4617. autoStopTime: 2, // 2 小时
  4618. autoStopTimeUnit: 'hour',
  4619. autoStopChapter: 5, // 5章
  4620.  
  4621. synth: speechSynthesis,
  4622. utterance: new SpeechSynthesisUtterance(),
  4623. }
  4624. },
  4625. components: {
  4626. PulseLoader
  4627. },
  4628. mounted() {
  4629. // 载入语音列表
  4630. this.voiceList = this.synth.getVoices();
  4631. this.synth.onvoiceschanged = () => {
  4632. this.voiceList = this.synth.getVoices();
  4633. };
  4634.  
  4635. this.loadSetting();
  4636. },
  4637. beforeDestory() {
  4638. clearTimeout(this.autoStopTimeId);
  4639. },
  4640. methods: {
  4641. formatMillisencod,
  4642. closeSpeech() {
  4643. this.$emit('closeSpeech');
  4644. },
  4645. loadSetting() {
  4646. this.rate = GM_getValue('speech.rate', 1);
  4647. this.pitch = GM_getValue('speech.pitch', 1);
  4648. this.selectedVoice = GM_getValue('speech.selectedVoice', 0);
  4649.  
  4650. this.autoStop = GM_getValue('speech.autoStop', '');
  4651. this.autoStopTime = GM_getValue('speech.autoStopTime', 2);
  4652. this.autoStopTimeUnit = GM_getValue('speech.autoStopTimeUnit', 'hour');
  4653. this.autoStopChapter = GM_getValue('speech.autoStopChapter', 5);
  4654. },
  4655. saveSetting() {
  4656. GM_setValue('speech.rate', this.rate);
  4657. GM_setValue('speech.pitch', this.pitch);
  4658. GM_setValue('speech.selectedVoice', this.selectedVoice);
  4659.  
  4660. GM_setValue('speech.autoStop', this.autoStop);
  4661. GM_setValue('speech.autoStopTime', this.autoStopTime);
  4662. GM_setValue('speech.autoStopTimeUnit', this.autoStopTimeUnit);
  4663. GM_setValue('speech.autoStopChapter', this.autoStopChapter);
  4664. },
  4665. start() {
  4666. this.isPlaying = true;
  4667.  
  4668. // 获取当前所在的章节
  4669. this.speakIndex = App.curFocusIndex;
  4670. this.startSpeakIndex = App.curFocusIndex;
  4671. let toSpeekText = this.getToSpeekText(true);
  4672.  
  4673. bus.$off(APPEND_NEXT_PAGE, this.waitForNext);
  4674. bus.$on(APPEND_NEXT_PAGE, this.waitForNext);
  4675.  
  4676. // fix 可能的问题:点击开始朗读无效,需要 cancel 才有效
  4677. speechSynthesis.cancel();
  4678.  
  4679. this.speak(toSpeekText, this.checkNext);
  4680.  
  4681. if (this.autoStop == 'time') {
  4682. clearTimeout(this.autoStopTimeId);
  4683. this.autoStopTimeId = setTimeout(this.stop, this.getAutoStopMillisecond());
  4684. }
  4685.  
  4686. // 保存设置
  4687. this.saveSetting();
  4688. },
  4689. getAutoStopMillisecond() {
  4690. if (this.autoStopTimeUnit == 'minute') {
  4691. return this.autoStopTime * 60 * 1000
  4692. } else {
  4693. return this.autoStopTime * 3600 * 1000
  4694. }
  4695. },
  4696. checkNext() {
  4697. if (!this.isPlaying) return
  4698.  
  4699. this.speakIndex += 1;
  4700. this.checkAgin();
  4701. },
  4702. checkAgin() {
  4703. let speakedChapters = this.speakIndex - this.startSpeakIndex;
  4704. if (this.autoStop == 'chapter' && speakedChapters >= this.autoStopChapter) {
  4705. this.stop();
  4706. return
  4707. }
  4708.  
  4709. // 是否有新章节
  4710. let nextText = this.getToSpeekText();
  4711. if (nextText) {
  4712. this.isFindingNext = false;
  4713. this.speak(nextText, this.checkNext);
  4714.  
  4715. this.scrollToNext();
  4716. } else {
  4717. this.isFindingNext = true;
  4718. // 加载下一章
  4719. App.scrollForce();
  4720. }
  4721. },
  4722. waitForNext() {
  4723. if (this.isFindingNext && this.isPlaying) {
  4724. this.checkAgin();
  4725. }
  4726. },
  4727. scrollToNext() {
  4728. let elem = App.scrollItems.get(this.speakIndex);
  4729. if (elem) {
  4730. App.scrollToArticle(elem);
  4731. }
  4732. },
  4733. getToSpeekText(fromSelection=false) {
  4734. let startIndex = this.speakIndex;
  4735.  
  4736. // 这是 jQuery 对象
  4737. let text = App.scrollItems
  4738. .toArray()
  4739. .filter((elem, i) => {
  4740. return i == startIndex
  4741. })
  4742. // .map(elem => elem.textContent.slice(0, 10)) // debug
  4743. .map(elem => elem.textContent)
  4744. .join('\n');
  4745.  
  4746. if (fromSelection) {
  4747. let newText = this.getSelectionAfterText(text);
  4748. if (newText) {
  4749. return newText
  4750. }
  4751. }
  4752.  
  4753. return text
  4754. },
  4755. getSelectionAfterText(text) {
  4756. const selObj = getSelection();
  4757. const selStr = selObj.toString();
  4758. let afterText;
  4759.  
  4760. if (!selStr) return
  4761.  
  4762. let indexes = locations(selStr, text);
  4763. if (indexes.length == 0) {
  4764. return
  4765. } else if (indexes.length == 1) {
  4766. afterText = text.substring(indexes[0]);
  4767. } else { // 多个
  4768. indexes = locations(selObj.anchorNode.data, text);
  4769. if (indexes.length == 0) return
  4770. else if (indexes.length == 1) {
  4771. let start = indexes[0] + selObj.anchorOffset;
  4772. afterText = text.substring(start);
  4773. } else {
  4774. console.error('getSelectionAfterText() 无法判断唯一');
  4775. }
  4776. }
  4777.  
  4778. selObj.removeAllRanges();
  4779. return afterText
  4780. },
  4781. speak(text, endFn) {
  4782. this.utterance = new SpeechSynthesisUtterance(text);
  4783. this.utterance.voice = this.voiceList[this.selectedVoice];
  4784. this.utterance.pitch = this.pitch;
  4785. this.utterance.rate = this.rate;
  4786.  
  4787. this.listenForSpeechEvents(endFn);
  4788.  
  4789. this.synth.speak(this.utterance);
  4790. },
  4791. listenForSpeechEvents (endFn) {
  4792. this.utterance.onstart = () => {
  4793. this.playState = STATE.playing;
  4794. };
  4795. this.utterance.onpause = (event) => {
  4796. this.playState = STATE.pausing;
  4797. this.elapsedTime = event.elapsedTime;
  4798. };
  4799. this.utterance.onresume = (e) => {
  4800. this.playState = STATE.playing;
  4801. };
  4802. this.utterance.onend = (event) => {
  4803. this.playState = STATE.stoping;
  4804. // this.elapsedTime = event.elapsedTime
  4805. this.elapsedTime = null;
  4806.  
  4807. if (endFn) {
  4808. endFn();
  4809. }
  4810. };
  4811. },
  4812. pause() {
  4813. this.isPlaying = false;
  4814.  
  4815. this.synth.pause();
  4816. },
  4817. resume() {
  4818. this.isPlaying = true;
  4819.  
  4820. this.synth.resume();
  4821. },
  4822. stop() {
  4823. this.isPlaying = false;
  4824.  
  4825. this.synth.cancel();
  4826.  
  4827. clearTimeout(this.autoStopTimeId);
  4828. }
  4829. }
  4830. };
  4831.  
  4832. var App$1 = {
  4833. render: function(){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{attrs:{"id":"app"}},[(_vm.speechDialogVisible)?_c('speech',{staticClass:"speech",on:{"closeSpeech":_vm.hideSpeech}}):_vm._e()],1)},
  4834. staticRenderFns: [],
  4835. data() {
  4836. return {
  4837. speechDialogVisible: false,
  4838. }
  4839. },
  4840. components: {
  4841. Speech,
  4842. },
  4843. created() {
  4844. bus.$on(SHOW_SPEECH, this.showSpeech);
  4845. },
  4846. beforeDestory() {
  4847. bus.$off(SHOW_SPEECH, this.hideSpeech);
  4848. },
  4849. methods: {
  4850. showSpeech() {
  4851. this.speechDialogVisible = true;
  4852. },
  4853. hideSpeech() {
  4854. this.speechDialogVisible = false;
  4855. }
  4856. }
  4857. };
  4858.  
  4859. function runVue() {
  4860. new Vue({
  4861. el: '#app',
  4862. render: h => h(App$1)
  4863. });
  4864. }
  4865.  
  4866. var App = {
  4867. isEnabled: false,
  4868. parsedPages: {},
  4869. pageNum: 1,
  4870. paused: false,
  4871. curPageUrl: location.href,
  4872. requestUrl: null,
  4873. iframe: null,
  4874. remove: [],
  4875. // 滚动激活相关
  4876. curFocusElement: null,
  4877. curFocusIndex: 1,
  4878.  
  4879. init: function() {
  4880. if (["mynovelreader-iframe", "superpreloader-iframe"].indexOf(window.name) != -1) { // 用于加载下一页的 iframe
  4881. return;
  4882. }
  4883.  
  4884. // 手动调用
  4885. var readx = function() {
  4886. // 防止 unsafeWindow cannot call: GM_getValue
  4887. setTimeout(function() {
  4888. App.launch();
  4889. }, 0);
  4890. };
  4891. try {
  4892. exportFunction(readx, unsafeWindow, {defineAs: "readx"});
  4893. } catch(ex) {
  4894. console.error('无法定义 readx 函数');
  4895. }
  4896.  
  4897.  
  4898. App.loadCustomSetting();
  4899. App.site = App.getCurSiteInfo();
  4900.  
  4901. if (App.site.startLaunch) {
  4902. App.site.startLaunch($(document));
  4903. }
  4904.  
  4905. var autoLaunch = App.isAutoLaunch();
  4906.  
  4907. if (autoLaunch === -1) {
  4908. return;
  4909. } else if (autoLaunch) {
  4910. if (App.site.mutationSelector) { // 特殊的启动:等待js把内容生成完毕
  4911. App.addMutationObserve(document, App.launch);
  4912. } else if (App.site.timeout) { // 延迟启动
  4913. setTimeout(App.launch, App.site.timeout);
  4914. } else { // NoScript 下 setTimeout 没用?
  4915. App.launch();
  4916. }
  4917. } else {
  4918. UI.addButton();
  4919. }
  4920. },
  4921. loadCustomSetting: function() {
  4922. var customRules;
  4923. try {
  4924. customRules = eval(Setting.customSiteinfo);
  4925. } catch (e) {
  4926. console.error('载入自定义站点配置错误', e);
  4927. }
  4928.  
  4929. if (_.isArray(customRules)) {
  4930. Rule.customRules = customRules;
  4931. C.log('载入自定义站点规则成功', customRules);
  4932. }
  4933.  
  4934. // load custom replace rules
  4935. Rule.customReplace = Rule.parseCustomReplaceRules(Setting.customReplaceRules);
  4936.  
  4937. C.log('载入自定义替换规则成功', Rule.customReplace);
  4938. },
  4939. getCurSiteInfo: function() {
  4940. var rules = Rule.customRules.concat(Rule.specialSite);
  4941. var locationHref = location.href;
  4942.  
  4943. var info = _.find(rules, function(x) {
  4944. return toRE(x.url).test(locationHref);
  4945. });
  4946.  
  4947. if (!info) {
  4948. info = {};
  4949. C.log("没有找到规则,尝试自动模式。");
  4950. } else {
  4951. C.log("找到规则:", info);
  4952. }
  4953. return info;
  4954. },
  4955. isAutoLaunch: function() {
  4956. var locationHref = window.location.href,
  4957. locationHost = location.host,
  4958. referrer = document.referrer;
  4959.  
  4960. switch (true) {
  4961. case L_getValue("mynoverlreader_disable_once") == 'true':
  4962. L_removeValue("mynoverlreader_disable_once");
  4963. return false;
  4964. // case location.hostname == 'www.fkzww.net' && !document.title.match(/网文快讯/): // 啃书只自动启用一个地方
  4965. // return false;
  4966. case Setting.booklink_enable && /booklink\.me/.test(referrer):
  4967. return true;
  4968. case locationHost == 'tieba.baidu.com':
  4969. var title = $('.core_title_txt').text();
  4970. if (title.match(Rule.titleRegExp)) {
  4971. return false;
  4972. } else {
  4973. return -1;
  4974. }
  4975. case Setting.getDisableAutoLaunch():
  4976. return false;
  4977. case GM_getValue("auto_enable"):
  4978. case config.soduso && /www\.sodu\.so/.test(referrer):
  4979. return true;
  4980. default:
  4981. return false;
  4982. }
  4983. },
  4984. addMutationObserve: function(doc, callback) {
  4985. var shouldAdd = false;
  4986. var $doc = $(doc);
  4987.  
  4988. if ($doc.find(App.site.contentSelector).size()) {
  4989. shouldAdd = false;
  4990. } else {
  4991. var mutationSelector = App.site.mutationSelector;
  4992. var target = $doc.find(mutationSelector)[0];
  4993. if (target) {
  4994. var childCount = App.site.mutationChildCount;
  4995. if (childCount === undefined || target.children.length <= childCount) {
  4996. shouldAdd = true;
  4997. }
  4998. }
  4999. }
  5000.  
  5001. if (shouldAdd) {
  5002. var observer = new MutationObserver(function(mutations) {
  5003. var nodeAdded = mutations.some(function(x) {
  5004. return x.addedNodes.length > 0;
  5005. });
  5006.  
  5007. if (nodeAdded) {
  5008. observer.disconnect();
  5009. callback();
  5010. }
  5011. });
  5012.  
  5013. observer.observe(target, {
  5014. childList: true
  5015. });
  5016.  
  5017. C.log("添加 MutationObserve 成功:", mutationSelector);
  5018. } else {
  5019. callback();
  5020. }
  5021. },
  5022. launch: function() {
  5023. // 只解析一次,防止多次重复解析一个页面
  5024. if (document.body && document.body.getAttribute("name") == "MyNovelReader") {
  5025. return App.toggle();
  5026. }
  5027.  
  5028. if (!App.site) {
  5029. App.site = App.getCurSiteInfo();
  5030. }
  5031.  
  5032. if (App.site.startFilter) {
  5033. try {
  5034. App.site.startFilter();
  5035. C.log('run startFilter function success');
  5036. } catch (ex) {
  5037. console.error('运行 startFilter function 错误', ex);
  5038. }
  5039. }
  5040.  
  5041. var parser = new Parser(App.site, document);
  5042. var hasContent = !!parser.hasContent();
  5043. if (hasContent) {
  5044. document.body.setAttribute("name", "MyNovelReader");
  5045. App.parsedPages[window.location.href] = true;
  5046. parser.getAll(function(parser) {
  5047. App.processPage(parser);
  5048. });
  5049. } else {
  5050. console.error("当前页面没有找到内容");
  5051. }
  5052.  
  5053. // 初始化, 取消页面限制等
  5054. if (App.site.fInit)
  5055. App.site.fInit();
  5056. },
  5057. processPage: function(parser) {
  5058. // 对 Document 进行处理
  5059. document.body.innerHTML = '';
  5060. App.prepDocument();
  5061. App.initDocument(parser);
  5062.  
  5063. runVue();
  5064.  
  5065. // cache vars
  5066. App.$doc = $(document);
  5067. App.$menuBar = App.$doc.find("#menu-bar");
  5068. App.$menu = App.$doc.find("#menu");
  5069. App.$content = App.$doc.find("#mynovelreader-content");
  5070. App.$loading = App.$doc.find("#loading");
  5071. App.$preferencesBtn = App.$doc.find("#preferencesBtn");
  5072.  
  5073. App.$menuHeader = App.$menu.find("#chapter-list");
  5074. App.$chapterList = App.$menu.find("#chapter-list");
  5075.  
  5076. App.indexUrl = parser.indexUrl;
  5077. App.prevUrl = parser.prevUrl; // 第一个上一页
  5078.  
  5079. App.oArticles = []; // 原始的内容,用于替换的无需刷新
  5080. App.parsers = [];
  5081.  
  5082. // 加入上一章的链接
  5083. if (parser.prevUrl) {
  5084. $("<li>")
  5085. .addClass('chapter')
  5086. .append(
  5087. $("<div>")
  5088. .attr({
  5089. "realHref": parser.prevUrl,
  5090. "onclick": "return false;"
  5091. })
  5092. .text("上一章".uiTrans())
  5093. )
  5094. .prependTo(App.$chapterList);
  5095. }
  5096.  
  5097. // 插入站点样式
  5098. if (App.site.style) {
  5099. GM_addStyle(App.site.style);
  5100. }
  5101.  
  5102. App.appendPage(parser, true);
  5103.  
  5104. App.registerControls();
  5105.  
  5106. // UI 的初始化
  5107. UI.init();
  5108.  
  5109. App.curFocusElement = $("article:first").get(0); // 初始化当前关注的 element
  5110. App.requestUrl = parser.nextUrl;
  5111. App.isTheEnd = parser.isTheEnd;
  5112.  
  5113. App.isEnabled = true;
  5114. UI.addButton();
  5115.  
  5116. // // 如果已经把当前焦点链接添加到历史记录,则滚动到顶部
  5117. // if (Setting.addToHistory) {
  5118. // window.scrollTo(0, 0);
  5119. // }
  5120.  
  5121. // 有些图片网站高度随着图片加载而变长
  5122. setTimeout(App.scroll, 1000);
  5123.  
  5124. App.cleanAgain();
  5125.  
  5126. if (config.PRELOADER) {
  5127. App.doRequest();
  5128. }
  5129. },
  5130. prepDocument: function() {
  5131. window.onload = window.onunload = function() {};
  5132.  
  5133. // 破解右键限制
  5134. var doc = document;
  5135. var bd = doc.body;
  5136. bd.onclick = bd.ondblclick = bd.onselectstart = bd.oncopy = bd.onpaste = bd.onkeydown = bd.oncontextmenu = bd.onmousemove = bd.onselectstart = bd.ondragstart = doc.onselectstart = doc.oncopy = doc.onpaste = doc.onkeydown = doc.oncontextmenu = null;
  5137. doc.onclick = doc.ondblclick = doc.onselectstart = doc.oncontextmenu = doc.onmousedown = doc.onkeydown = function() {
  5138. return true;
  5139. };
  5140.  
  5141. doc = document.wrappedJSObject || document;
  5142. doc.onmouseup = null;
  5143. doc.onmousedown = null;
  5144. doc.oncontextmenu = null;
  5145.  
  5146. var arAllElements = document.getElementsByTagName('*');
  5147. for (var i = arAllElements.length - 1; i >= 0; i--) {
  5148. var elmOne = arAllElements[i];
  5149. elmOne = elmOne.wrappedJSObject || elmOne;
  5150. elmOne.onmouseup = null;
  5151. elmOne.onmousedown = null;
  5152. }
  5153.  
  5154. $(document).unbind("keypress");
  5155. $(document).unbind("keydown");
  5156.  
  5157. // remove body style
  5158. $('link[rel="stylesheet"], script').remove();
  5159. $('body')
  5160. .removeAttr('style')
  5161. .removeAttr('bgcolor');
  5162.  
  5163. $('style:not(.noRemove)').filter(function() {
  5164. var $style = $(this);
  5165. if($style.text().indexOf('#cVim-link-container') != -1) { // chrome 的 cVim 扩展
  5166. return false;
  5167. }
  5168. return true;
  5169. }).remove();
  5170. },
  5171. initDocument: function(parser) {
  5172. document.title = parser.docTitle;
  5173.  
  5174. document.body.innerHTML = $.nano(tpl_mainHtml.uiTrans(), parser);
  5175. },
  5176. clean: function() {
  5177. $('body > *:not("#container, .readerbtn, .noRemove, #reader_preferences, #uil_blocker,iframe[name=\'mynovelreader-iframe\']")').remove();
  5178. $('link[rel="stylesheet"]:not(.noRemove)').remove();
  5179. $('body, #container').removeAttr('style').removeAttr('class');
  5180.  
  5181. if (unsafeWindow.jQuery && location.host.indexOf('qidian') > 0) {
  5182. unsafeWindow.jQuery(document).off("selectstart").off("contextmenu");
  5183. }
  5184. },
  5185. cleanAgain: function() {
  5186. // var host = location.host;
  5187. // if (!host.match(/qidian\.com|zongheng\.com/)) { // 只在起点、纵横等网站运行
  5188. // return;
  5189. // }
  5190.  
  5191. // 再次移除其它不相关的,起点,纵横中文有时候有问题
  5192. setTimeout(App.clean, 2000);
  5193. setTimeout(App.clean, 5000);
  5194. setTimeout(App.clean, 8000);
  5195. // TM 用 addEventListener('load') 有问题
  5196. window.onload = function() {
  5197. App.clean();
  5198. setTimeout(App.clean, 500);
  5199. };
  5200. },
  5201. toggle: function() {
  5202. if (App.isEnabled) { // 退出
  5203. GM_setValue("auto_enable", false);
  5204. L_setValue("mynoverlreader_disable_once", true);
  5205.  
  5206. location.href = App.activeUrl;
  5207. } else {
  5208. GM_setValue("auto_enable", true);
  5209. L_removeValue("mynoverlreader_disable_once");
  5210. App.isEnabled = true;
  5211. App.launch();
  5212. }
  5213. },
  5214. removeListener: function() {
  5215. C.log("移除各种事件监听");
  5216. App.remove.forEach(function(_remove) {
  5217. _remove();
  5218. });
  5219. },
  5220. appendPage: function(parser, isFirst) {
  5221. var chapter = $("article:last");
  5222. if (chapter.length && parser.isSection) { // 每次获取的不是一章,而是一节
  5223. var lastText = chapter.find("p:last").remove().text().trim();
  5224. var newPage = parser.content.replace(/<p>\s+/, "<p>" + lastText);
  5225.  
  5226. chapter
  5227. .find(".chapter-footer-nav").remove()
  5228. .end()
  5229. .append(newPage);
  5230.  
  5231. if (!Setting.hide_footer_nav) {
  5232. chapter.append($.nano(UI.tpl_footer_nav, parser));
  5233. }
  5234.  
  5235. } else {
  5236. chapter = $("<article>")
  5237. .attr("id", "page-" + App.pageNum)
  5238. .append(
  5239. $("<h1>").addClass("title").text(parser.chapterTitle)
  5240. )
  5241. .append(parser.content)
  5242. .appendTo(App.$content);
  5243.  
  5244. if (!Setting.hide_footer_nav) {
  5245. chapter.append($.nano(UI.tpl_footer_nav, parser));
  5246. }
  5247.  
  5248. // App.fixImageFloats(chapter.get(0));
  5249.  
  5250. // 添加到章节列表
  5251. var chapterItem = $("<li>")
  5252. .addClass('chapter')
  5253. .append(
  5254. $("<div>")
  5255. .attr({
  5256. href: "#page-" + App.pageNum,
  5257. "realHref": parser.curPageUrl,
  5258. onclick: "return false;",
  5259. title: parser.chapterTitle
  5260. })
  5261. .text(parser.chapterTitle)
  5262. )
  5263. .prependTo(App.$chapterList);
  5264.  
  5265. if (isFirst) {
  5266. chapterItem.addClass('active');
  5267. }
  5268.  
  5269. App.pageNum += 1;
  5270. App.resetCache();
  5271. }
  5272.  
  5273. App.oArticles.push(chapter[0].outerHTML);
  5274. App.parsers.push(parser);
  5275.  
  5276. bus.$emit(APPEND_NEXT_PAGE);
  5277. },
  5278. resetCache: function() { // 更新缓存变量
  5279. App.menuItems = App.$chapterList.find("div");
  5280. App.scrollItems = $("article");
  5281. },
  5282. registerControls: function() {
  5283. // 内容滚动
  5284. var throttled = _.throttle(App.scroll, 200);
  5285. $(window).scroll(throttled);
  5286.  
  5287. App.registerKeys();
  5288.  
  5289. if (Setting.dblclickPause) {
  5290. App.$content.on("dblclick", function() {
  5291. App.pauseHandler();
  5292. });
  5293. }
  5294.  
  5295. // 左侧章节列表
  5296. App.$menuHeader.click(function() {
  5297. App.copyCurTitle();
  5298. });
  5299.  
  5300. App.$menuBar.click(function() {
  5301. UI.hideMenuList();
  5302. });
  5303.  
  5304. App.$doc.on("mousedown", "#chapter-list div", function(event) {
  5305. switch (event.which) {
  5306. case 1:
  5307. var href = $(this).attr("href");
  5308. if (href) {
  5309. App.scrollToArticle($(href));
  5310. } else {
  5311. location.href = $(this).attr("realHref");
  5312. }
  5313. break;
  5314. case 2: // middle click
  5315. L_setValue("mynoverlreader_disable_once", true);
  5316. App.openUrl($(this).attr("realHref"));
  5317. break;
  5318. }
  5319. });
  5320.  
  5321. $("#preferencesBtn").click(function(event) {
  5322. event.preventDefault();
  5323. UI.preferencesShow();
  5324. });
  5325.  
  5326. GM_registerMenuCommand("小说阅读脚本设置".uiTrans(), UI.preferencesShow.bind(UI));
  5327. },
  5328. registerKeys: function() {
  5329. key('enter', function(event) {
  5330. if (UI.$prefs) {
  5331. return;
  5332. }
  5333.  
  5334. App.openUrl(App.indexUrl, "主页链接没有找到".uiTrans());
  5335. App.copyCurTitle();
  5336.  
  5337. event.stopPropagation();
  5338. event.preventDefault();
  5339. });
  5340.  
  5341. key('left', function(event) {
  5342. var scrollTop = $(window).scrollTop();
  5343. if (scrollTop === 0) {
  5344. location.href = App.prevUrl;
  5345. } else {
  5346. var offsetTop = $(App.curFocusElement).offset().top;
  5347. // 在视野窗口内
  5348. if (offsetTop > scrollTop && offsetTop < (scrollTop + $(window).height())) {
  5349. App.scrollToArticle(App.curFocusElement.previousSibling || 0);
  5350. } else {
  5351. App.scrollToArticle(App.curFocusElement);
  5352. }
  5353. }
  5354. return false;
  5355. });
  5356.  
  5357. key('right', function(event) {
  5358. if (App.getRemain() === 0) {
  5359. location.href = App.lastRequestUrl || App.requestUrl;
  5360. } else {
  5361. App.scrollToArticle(App.curFocusElement.nextSibling || App.$doc.height());
  5362. }
  5363.  
  5364. event.preventDefault();
  5365. event.stopPropagation();
  5366. return false;
  5367. });
  5368.  
  5369. key('esc', function(){
  5370. if (UI.$prefs) {
  5371. UI.hide();
  5372. return false;
  5373. }
  5374. });
  5375.  
  5376. key('shift+/', function() {
  5377. UI.openHelp();
  5378. return false;
  5379. });
  5380.  
  5381. key(Setting.quietModeKey, function(){
  5382. UI.toggleQuietMode();
  5383. return false;
  5384. });
  5385.  
  5386. key(Setting.hideMenuListKey, function(){
  5387. UI.hideMenuList();
  5388. return false;
  5389. });
  5390.  
  5391. key(Setting.openPreferencesKey, function(){
  5392. UI.preferencesShow();
  5393. return false;
  5394. });
  5395.  
  5396. key(Setting.openSpeechKey, function() {
  5397. bus.$emit(SHOW_SPEECH);
  5398. return false;
  5399. });
  5400. },
  5401. copyCurTitle: function() {
  5402. if (Setting.copyCurTitle) {
  5403. var title = $(App.curFocusElement).find(".title").text()
  5404. .replace(/第?\S+章/, "").trim();
  5405.  
  5406. GM_setClipboard(title, "text");
  5407. }
  5408. },
  5409. scrollToArticle: function(elem) {
  5410. var offsetTop;
  5411. if (typeof elem == "number") {
  5412. offsetTop = elem;
  5413. } else {
  5414. offsetTop = $(elem).offset().top - parseInt($(elem).css("margin-top"), 10);
  5415. }
  5416.  
  5417. if (Setting.scrollAnimate) {
  5418. $("html, body").stop().animate({
  5419. scrollTop: offsetTop
  5420. }, 750, "easeOutExpo");
  5421. } else {
  5422. $("html, body").stop().scrollTop(offsetTop);
  5423. }
  5424. },
  5425. openUrl: function(url, errorMsg) {
  5426. if (url) {
  5427. // ff30 Greasemonkey 会报错:Greasemonkey 访问违规:unsafeWindow 无法调用 GM_openInTab。新建脚本采用按键调用也这样。
  5428. setTimeout(function() {
  5429. GM_openInTab(url, false);
  5430. }, 0);
  5431. } else if (errorMsg) {
  5432. UI.notice(errorMsg);
  5433. }
  5434. },
  5435. pauseHandler: function() {
  5436. App.paused = !App.paused;
  5437. if (App.paused) {
  5438. UI.notice('<b>状态</b>:自动翻页<span style="color:red!important;"><b>暂停</b></span>'.uiTrans());
  5439. App.$loading.html('自动翻页已经<span style="color:red!important;"><b>暂停</b></span>'.uiTrans()).show();
  5440. } else {
  5441. UI.notice('<b>状态</b>:自动翻页<span style="color:red!important;"><b>启用</b></span>'.uiTrans());
  5442. App.scroll();
  5443. }
  5444. },
  5445. scroll: function() {
  5446. if (!App.paused && !App.working && App.getRemain() < Setting.remain_height) {
  5447. App.scrollForce();
  5448. }
  5449.  
  5450. if (App.isTheEnd) {
  5451. App.$loading.html("已到达最后一页...".uiTrans()).show();
  5452. }
  5453.  
  5454. App.updateCurFocusElement();
  5455. },
  5456. scrollForce: function() {
  5457. if (App.tmpDoc) {
  5458. App.loaded(App.tmpDoc);
  5459. } else {
  5460. App.doRequest();
  5461. }
  5462. },
  5463. updateCurFocusElement: function() { // 滚动激活章节列表
  5464. // Get container scroll position
  5465. var fromTop = $(window).scrollTop() + $(window).height() / 2;
  5466.  
  5467. // Get id of current scroll item
  5468. var cur = App.scrollItems.map(function() {
  5469. if ($(this).offset().top < fromTop)
  5470. return this;
  5471. });
  5472. // Get the id of the current element
  5473. App.curFocusIndex = cur.length - 1;
  5474. cur = cur[cur.length - 1];
  5475. var id = cur ? cur.id : "";
  5476.  
  5477. if (App.lastId !== id) {
  5478. App.lastId = id;
  5479.  
  5480. var activeItem = App.menuItems.filter("[href=#" + id + "]"),
  5481. activeTitle = activeItem.text(),
  5482. activeUrl = activeItem.attr("realHref");
  5483.  
  5484. // Set/remove active class
  5485. App.menuItems.parent().removeClass("active");
  5486. activeItem.parent().addClass("active");
  5487.  
  5488. App.curFocusElement = cur;
  5489. App.activeUrl = activeUrl;
  5490.  
  5491. if (Setting.addToHistory) {
  5492. var curNum = id.match(/\d+/)[0] - 1; // 当前是第几个
  5493. var curTitle = App.parsers[curNum].docTitle;
  5494. document.title = curTitle;
  5495.  
  5496. // 有域名的限制,起点过渡到 vip 章节无法生效
  5497. var url = activeUrl.replace('http://read.qidian.com', '');
  5498. try {
  5499. unsafeWindow.history.pushState(null, curTitle, url);
  5500. } catch (e) {
  5501. console.error('添加下一页到历史记录失败', e);
  5502. }
  5503. }
  5504. }
  5505. },
  5506. getRemain: function() {
  5507. var scrollHeight = Math.max(document.documentElement.scrollHeight,
  5508. document.body.scrollHeight);
  5509. var remain = scrollHeight - window.innerHeight - window.scrollY;
  5510. return remain;
  5511. },
  5512. doRequest: function() {
  5513. App.working = true;
  5514. var nextUrl = App.requestUrl;
  5515. App.lastRequestUrl = App.requestUrl;
  5516.  
  5517. if (nextUrl && !App.isTheEnd && !(nextUrl in App.parsedPages)) {
  5518. App.parsedPages[nextUrl] = 0;
  5519. App.curPageUrl = App.requestUrl;
  5520. App.requestUrl = null;
  5521.  
  5522. var useiframe = App.site.useiframe;
  5523.  
  5524. App.$loading
  5525. .show()
  5526. .html("")
  5527. .append($("<img>").attr("src", "data:image/gif;base64,R0lGODlhEAAQAMQAAPf39+/v7+bm5t7e3tbW1s7OzsXFxb29vbW1ta2traWlpZycnJSUlIyMjISEhHt7e3Nzc2tra2NjY1paWlJSUkpKSkJCQjo6OjExMSkpKSEhIRkZGRAQEAgICAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJBQAeACwAAAEADwAOAAAFdaAnet20GAUCceN4LQlyFMRATC3GLEqM1gIc6dFgPDCii6I2YF0eDkinxUkMBBAPBfLItESW2sEjiWS/ItqALJGgRZrNRtvWoDlxFqZdmbY0cVMdbRMWcx54eSMZExQVFhcYGBmBfxWPkZQbfi0dGpIYGiwjIQAh+QQJBQAeACwAAAEADwAOAAAFeKAnep0FLQojceOYQU6DIsdhtVoEywptEBRRZyKBQDKii+JHYGEkxE6LkyAMIB6KRKJpJQuDg2cr8Y7AgjHULCoQ0pUJZWO+uBGeDIVikbYyDgRYHRUVFhcsHhwaGhsYfhuHFxgZGYwbHH4iHBiUlhuYmlMbjZktIQAh+QQFBQAeACwAAAEADwAOAAAFe6Aneh1GQU9UdeOoTVIEOQ2zWG0mSVP0ODYF4iLq7HgaEaaRQCA4HsyOwhp1FgdDxFOZTDYt0cVQSHgo6PCIPOBWKmpRgdDGWCzQ8KUwOHg2FxcYYRwJdBAiGRgZGXkcC3MEjhkalZYTfBMtHRudnhsKcGodHKUcHVUeIQAh+QQJBQAeACwAAAEADwAOAAAFbKAnjp4kURiplmYEQemoTZMpuY/TkBVFVRtRJtJgMDoejaViWT0WiokHc2muMIoEY0pdiRCIgyeDia0OhoJnk8l4PemEh6OprxQFQkS02WiCIhd4HmoiHRx9ImkEA14ciISMBFJeSAQIEBwjIQAh+QQJBQAeACwAAAEADwAOAAAFd6Anel1WTRKFdeO4WRWFStKktdwFU3JNZ6MM5nLZiDQTCCTC4ghXrU7k4bB4NpoMpyXKNBqQa5Y7YiwWHg6WLFK4SWoW95JAMOAbI05xOEhEHWoaFyJ0BgYHWyIcHA4Fj48EBFYtGJKSAwMFFGQdEAgCAgcQih4hACH5BAkFAB4ALAAAAQAPAA4AAAV0oCeKG2ZVFtaNY6dh10lNU8Z2WwbLkyRpI85Gk+GQKr7JqiME3mYSjIe5WbE8GkhkMhVeR48HpLv5ihoOB9l4xTAYYw9nomCLOgzFoiJSEAoIFiIXCwkJC1YVAwMEfwUGBgeBLBMEAouOBxdfHA8HlwgRdiEAIfkECQUAHgAsAAABAA8ADgAABXOgJ4rdpmWZ1o0sZ2YYdlka63XuKVsVVZOuzcrDufQoQxzH1rFMJJiba8jaPCnSjW30lHgGhMJWBIl4D2DLNvOATDwPwSCxHHUgjseFOJAn1B4YDgwND0MTAWAFBgcICgsMUVwDigYICQt7NhwQCGELE1QhACH5BAkFAB4ALAAAAQAPAA4AAAV4oCeOHWdyY+p1JbdpWoam7fZmGYZtYoeZm46Ik7kYhZBBQ6PyWSoZj0FAuKg8mwrF4glQryIKZdL9gicTiVQw4Ko2aYrnwUbMehGJBOPhDAYECVYeGA8PEBNCHhOABgcJCgwNh0wjFQaOCAoLk1EqHBILmg8Vih4hACH5BAkFAB4ALAAAAQAPAA4AAAV6oCd6Hdmd5ThWCee+XCpOwTBteL6lnCAMLVFHQ9SIHgHBgaPyZDKYjcfwszQ9HMwl40kOriKLuDsggD2VtOcwKFibGwrFCiEUEjJSZTLhcgwGBwsYIhkUEhITKRYGCAkKDA0PiBJcKwoKCwwODxETRk0dFA8NDhIYMiEAIfkECQUAHgAsAAABAA8ADgAABXmgJ3rcYwhcN66eJATCsHEpOwXwQGw8rZKDGMIi6vBmokcswWFtNBvVQUdkcTJQj67AGmEyGU+hYOiKMGiP4oC4dDmXS1iCSDR+xYvFovF0FAoLDxgiGxYUFRY/FwsMDQ4PEhOTFH0jFw6QEBKcE5YrHRcTERIUGHghACH5BAkFAB4ALAAAAQAPAA4AAAV4oCd63GMAgfF04zgNQixjrVcJQz4QRLNxI06Bh7CILpkf0CMpGBLL0ebHWhwOl5qno/l5EGCtqAtUmMWeTNfzWCxoNU4maWs0Vq0OBpMBdh4ODxEaIhsXhxkjGRAQEhITExQVFhdRHhoTjo8UFBYbWnoUjhUZLCIhACH5BAkFAB4ALAAAAQAPAA4AAAV5oCd6HIQIgfFw42gZBDEMgjBMbXUYRlHINEFF1FEgEIqLyHKQJToeikLBgI44iskG+mAsMC0RR7NhNRqM8IjMejgcahHbM4E8Mupx2YOJSCZWIxlkUB0TEhIUG2IYg4tyiH8UFRaNGoEeGYgTkxYXGZhEGBWTGI8iIQA7"))
  5528. .append("<a href='" + nextUrl + "' title='点击打开下一页链接'>正在载入下一页".uiTrans() + (useiframe ? "(iframe)" : "") + "...</a>");
  5529.  
  5530. setTimeout(function() {
  5531. if (useiframe) {
  5532. App.iframeRequest(nextUrl);
  5533. } else {
  5534. App.httpRequest(nextUrl, App.httpRequestDone);
  5535. }
  5536. }, App.site.nDelay || 0);
  5537. } else {
  5538. // App.$loading.html("<a href='" + App.curPageUrl + "'>无法使用阅读模式,请手动点击下一页</a>").show();
  5539. }
  5540. },
  5541. httpRequest: function(nextUrl, callback) {
  5542. if (!_.isFunction(callback)) {
  5543. callback = function() {};
  5544. }
  5545.  
  5546. C.log("获取下一页: " + nextUrl);
  5547. App.parsedPages[nextUrl] += 1;
  5548.  
  5549. GM_xmlhttpRequest({
  5550. url: nextUrl,
  5551. method: "GET",
  5552. overrideMimeType: "text/html;charset=" + document.characterSet,
  5553. timeout: config.xhr_time,
  5554. onload: function(res) {
  5555. var doc = parseHTML(res.responseText);
  5556. callback(doc, nextUrl);
  5557. },
  5558. ontimeout: function() {
  5559. callback(null, nextUrl);
  5560. }
  5561. });
  5562. },
  5563. httpRequestDone: function(doc, nextUrl) {
  5564. if (doc) {
  5565. App.beforeLoad(doc);
  5566. return;
  5567. }
  5568.  
  5569. if (App.parsedPages[nextUrl] >= 3) {
  5570. console.error('同一个链接已获取3次', nextUrl);
  5571. App.$loading.html("<a href='" + nextUrl + "'>无法获取下一页,请手动点击</a>").show();
  5572. return;
  5573. }
  5574.  
  5575. // 无内容再次尝试获取
  5576. console.error('连接超时, 再次获取');
  5577. App.httpRequest(nextUrl, App.httpRequestDone);
  5578. },
  5579. iframeRequest: function(nextUrl) {
  5580. C.log("iframeRequest: " + nextUrl);
  5581. if (!App.iframe) {
  5582. var i = document.createElement('iframe');
  5583. App.iframe = i;
  5584. i.name = 'mynovelreader-iframe';
  5585. i.width = '100%';
  5586. i.height = '0';
  5587. i.frameBorder = "0";
  5588. i.style.cssText = '\
  5589. margin:0!important;\
  5590. padding:0!important;\
  5591. visibility:hidden!important;\
  5592. ';
  5593. i.src = nextUrl;
  5594. i.addEventListener('load', App.iframeLoaded, false);
  5595. App.remove.push(function() {
  5596. i.removeEventListener('load', App.iframeLoaded, false);
  5597. });
  5598. document.body.appendChild(i);
  5599. } else {
  5600. App.iframe.contentDocument.location.replace(nextUrl);
  5601. }
  5602. },
  5603. iframeLoaded: function() {
  5604. var iframe = this;
  5605. var body = iframe.contentDocument.body;
  5606.  
  5607. if (body && body.firstChild) {
  5608. var doc = iframe.contentDocument;
  5609.  
  5610. if (App.site.startLaunch) {
  5611. App.site.startLaunch($(doc));
  5612. }
  5613.  
  5614. var mutationSelector = App.site.mutationSelector;
  5615. if (mutationSelector) {
  5616. App.addMutationObserve(doc, function() {
  5617. App.beforeLoad(doc);
  5618. });
  5619. } else {
  5620. var timeout = App.site.timeout || 0;
  5621.  
  5622. setTimeout(function() {
  5623. App.beforeLoad(doc);
  5624. }, timeout);
  5625. }
  5626. }
  5627. },
  5628. beforeLoad: function(htmlDoc) {
  5629. if (config.PRELOADER) {
  5630. App.tmpDoc = htmlDoc;
  5631. App.working = false;
  5632. App.scroll();
  5633.  
  5634. // 预读图片
  5635. var existSRC = {};
  5636. $(App.tmpDoc).find('img').each(function() {
  5637. var isrc = $(this).attr('src');
  5638. if (!isrc || existSRC[isrc]) {
  5639. return;
  5640. } else {
  5641. existSRC[isrc] = true;
  5642. }
  5643. var img = document.createElement('img');
  5644. img.src = isrc;
  5645. });
  5646. } else {
  5647. App.loaded(htmlDoc);
  5648. }
  5649. },
  5650. loaded: function(doc) {
  5651. var parser = new Parser(App.site, doc, App.curPageUrl);
  5652. parser.getAll(function() {
  5653. App.addNextPage(parser);
  5654. });
  5655. App.tmpDoc = null;
  5656. },
  5657. addNextPage: function(parser) {
  5658. if (parser.content) {
  5659. App.appendPage(parser);
  5660.  
  5661. App.$loading.hide();
  5662. App.requestUrl = parser.nextUrl;
  5663. App.isTheEnd = parser.isTheEnd;
  5664.  
  5665. App.afterLoad();
  5666. } else {
  5667. App.removeListener();
  5668.  
  5669. var msg = (parser.isTheEnd == 'vip') ?
  5670. 'vip 章节,需付费。' :
  5671. '错误:没有找到下一页的内容。';
  5672. App.$loading.html(
  5673. '<a href="' + App.curPageUrl + '">' + msg + '点此打开下一页。</a>'.uiTrans())
  5674. .show();
  5675. }
  5676.  
  5677. App.working = false;
  5678. },
  5679. afterLoad: function() {
  5680. App.tmpDoc = null;
  5681.  
  5682. if (config.PRELOADER) {
  5683. setTimeout(function(){
  5684. App.doRequest();
  5685. }, 200);
  5686. }
  5687. },
  5688. fixImageFloats: function(articleContent) {
  5689. if (!config.fixImageFloats) return;
  5690.  
  5691. articleContent = articleContent || document;
  5692.  
  5693. var imageWidthThreshold = Math.min(articleContent.offsetWidth, 800) * 0.55,
  5694. images = articleContent.querySelectorAll('img:not(.blockImage)');
  5695.  
  5696. for (var i = 0, il = images.length; i < il; i += 1) {
  5697. var image = images[i];
  5698.  
  5699. if (image.offsetWidth > imageWidthThreshold) {
  5700. image.className += " blockImage";
  5701. }
  5702. }
  5703. },
  5704.  
  5705. isSaveing: false,
  5706. saveAsTxt: function() {
  5707. if (App.site.useiframe) {
  5708. UI.notice('暂不支持', 3000);
  5709. return;
  5710. }
  5711.  
  5712. if (App.isSaveing) {
  5713. alert('正在保存中,请稍后');
  5714. return;
  5715. }
  5716.  
  5717. App.isSaveing = true;
  5718.  
  5719. run(App.parsers, function() {
  5720. App.isSaveing = false;
  5721. });
  5722. }
  5723. };
  5724.  
  5725. var UI = {
  5726. tpl_footer_nav: '\
  5727. <div class="chapter-footer-nav">\
  5728. <a class="prev-page" href="{prevUrl}">上一页</a> | \
  5729. <a class="index-page" href="{indexUrl}" title="Enter 键打开目录">目录</a> | \
  5730. <a class="next-page" style="color:{theEndColor}" href="{nextUrl}">下一页</a>\
  5731. </div>\
  5732. '.uiTrans(),
  5733. skins: {},
  5734.  
  5735. init: function(){
  5736. UI.refreshMainStyle();
  5737.  
  5738. UI.refreshSkinStyle(Setting.skin_name, true);
  5739.  
  5740. UI.refreshExtraStyle(Setting.extra_css);
  5741.  
  5742. UI.fixMobile();
  5743.  
  5744. // 初始变量
  5745. UI.$menu = $('#menu');
  5746. UI.$menuBar = $('#menu-bar');
  5747. UI.$content = $('#mynovelreader-content');
  5748. UI.$preferencesBtn = $('#preferencesBtn');
  5749.  
  5750. // 初始化是否隐藏
  5751. if(Setting.hide_footer_nav){
  5752. UI.hideFooterNavStyle(true);
  5753. }
  5754.  
  5755. // UI.toggleQuietMode(); // 初始化安静模式
  5756. UI.hideMenuList(Setting.menu_list_hiddden); // 初始化章节列表是否隐藏
  5757. UI.hidePreferencesButton(Setting.hide_preferences_button); // 初始化设置按钮是否隐藏
  5758. },
  5759. refreshMainStyle: function(){
  5760. var mainCss = Res.CSS_MAIN
  5761. .replace("{font_family}", Setting.font_family)
  5762. .replace("{font_size}", UI.calcContentFontSize(Setting.font_size))
  5763. .replace("{title_font_size}", UI.calcTitleFontSize(Setting.font_size))
  5764. .replace("{content_width}", Setting.content_width)
  5765. .replace("{text_line_height}", Setting.text_line_height)
  5766. .replace("{menu-bar-hidden}", Setting.menu_bar_hidden ? "display:none;" : "");
  5767.  
  5768. if(UI.$mainStyle){
  5769. UI.$mainStyle.text(mainCss);
  5770. return;
  5771. }
  5772.  
  5773. UI.$mainStyle = $('<style id="main">')
  5774. .text(mainCss)
  5775. .appendTo('head');
  5776. },
  5777. hideFooterNavStyle: function(hidden){
  5778. var navStyle = $("#footer_nav_css");
  5779. if(hidden) {
  5780. if(navStyle.length === 0) {
  5781. $('<style>')
  5782. .attr("id", "footer_nav_css")
  5783. .text(".chapter-footer-nav { display: none; }")
  5784. .appendTo('head');
  5785. }
  5786. } else {
  5787. navStyle.remove();
  5788. }
  5789. },
  5790. hideMenuList: function(hidden){
  5791. if(typeof(hidden) === "undefined"){
  5792. hidden = !UI.menu_list_hiddden;
  5793. }
  5794.  
  5795. if(hidden){
  5796. UI.$menu.addClass('hidden');
  5797. UI.$content.css("margin-left", "");
  5798. }else{
  5799. UI.$menu.removeClass('hidden');
  5800. UI.$content.css("margin-left", "320px");
  5801. }
  5802. UI.menu_list_hiddden = hidden;
  5803. },
  5804. hidePreferencesButton: function(hidden) {
  5805. hidden = _.isUndefined(hidden) ? Setting.hide_preferences_button : hidden;
  5806.  
  5807. UI.$preferencesBtn.toggle(!hidden);
  5808. },
  5809. hideMenuBar: function(hidden) {
  5810. hidden = _.isUndefined(hidden) ? Setting.menu_bar_hidden : hidden;
  5811.  
  5812. UI.$menuBar.toggle(!hidden);
  5813. },
  5814. refreshSkinStyle: function(skin_name, isFirst){
  5815. var $style = $("#skin_style");
  5816. if($style.length === 0){
  5817. $style = $('<style id="skin_style">').appendTo('head');
  5818. }
  5819.  
  5820. // 图片章节夜间模式会变的无法看
  5821. if (isFirst && skin_name.indexOf('夜间'.uiTrans()) != -1 && Setting.picNightModeCheck) {
  5822. setTimeout(function(){
  5823. var img = $('#mynovelreader-content img')[0];
  5824. // console.log(img.width, img.height)
  5825. if (img && img.width > 500 && img.height > 1000) {
  5826. $style.text(UI.skins['缺省皮肤'.uiTrans()]);
  5827. return;
  5828. }
  5829. }, 200);
  5830. }
  5831.  
  5832. $style.text(UI.skins[skin_name]);
  5833. },
  5834. refreshExtraStyle: function(css){
  5835. var style = $("#extra_style");
  5836. if(style.length === 0){
  5837. style = $('<style id="extra_style">').appendTo('head');
  5838. }
  5839.  
  5840. style.text(css);
  5841. },
  5842. toggleQuietMode: function() {
  5843. this._isQuietMode = !this._isQuietMode;
  5844. var selector = '#menu-bar, #menu, #preferencesBtn, .readerbtn';
  5845.  
  5846. if (this.$_quietStyle) {
  5847. this.$_quietStyle.remove();
  5848. this.$_quietStyle = null;
  5849. }
  5850.  
  5851. if (this._isQuietMode) {
  5852. $(selector).addClass("quiet-mode");
  5853.  
  5854. if (!isChrome) { // firefox 下隐藏滚动条
  5855. this.$_quietStyle = $('<style>')
  5856. .text('scrollbar {visibility:collapse !important; } body {overflow: hidden !important; overflow-x: hidden !important;}')
  5857. .appendTo('head');
  5858. }
  5859. } else {
  5860. $(selector).removeClass("quiet-mode");
  5861. }
  5862. },
  5863. addButton: function(){
  5864. GM_addStyle('\
  5865. .readerbtn {\
  5866. position: fixed;\
  5867. right: 10px;\
  5868. bottom: 10px;\
  5869. z-index: 2247483648;\
  5870. padding: 20px 5px;\
  5871. width: 50px;\
  5872. height: 20px;\
  5873. line-height: 20px;\
  5874. text-align: center;\
  5875. border: 1px solid;\
  5876. border-color: #888;\
  5877. border-radius: 50%;\
  5878. background: rgba(0,0,0,.5);\
  5879. color: #FFF;\
  5880. font: 12px/1.5 "微软雅黑","宋体",Arial;\
  5881. cursor: pointer;\
  5882. }\
  5883. ');
  5884.  
  5885. $("<div>")
  5886. .addClass("readerbtn")
  5887. .html(App.isEnabled ? "退出".uiTrans() : "阅读模式".uiTrans())
  5888. .mousedown(function(event){
  5889. if(event.which == 1){
  5890. App.toggle();
  5891. }else if(event.which == 2){
  5892. event.preventDefault();
  5893. L_setValue("mynoverlreader_disable_once", true);
  5894.  
  5895. var url = App.activeUrl || App.curPageUrl;
  5896. App.openUrl(url);
  5897. }
  5898. })
  5899. .appendTo('body');
  5900. },
  5901. calcContentFontSize: function(fontSizeStr) {
  5902. var m = fontSizeStr.match(/([\d\.]+)(px|r?em|pt)/);
  5903. if(m) {
  5904. var size = m[1],
  5905. type = m[2];
  5906. return parseFloat(size, 10) + type;
  5907. }
  5908.  
  5909. m = fontSizeStr.match(/([\d\.]+)/);
  5910. if (m) {
  5911. return parseFloat(m[1], 10) + 'px';
  5912. }
  5913.  
  5914. return "";
  5915. },
  5916. calcTitleFontSize: function(fontSizeStr){
  5917. var m = fontSizeStr.match(/([\d\.]+)(px|r?em|pt)/);
  5918. if(m) {
  5919. var size = m[1],
  5920. type = m[2];
  5921. return parseFloat(size, 10) * 1.8 + type;
  5922. }
  5923.  
  5924. m = fontSizeStr.match(/([\d\.]+)/);
  5925. if (m) {
  5926. return parseFloat(m[1], 10) * 1.8 + 'px';
  5927. }
  5928.  
  5929. return "";
  5930. },
  5931. fixMobile: function(){ // 自适应网页设计
  5932. var meta = document.createElement("meta");
  5933. meta.setAttribute("name", "viewport");
  5934. meta.setAttribute("content", "width=device-width, initial-scale=1");
  5935. document.head.appendChild(meta);
  5936. },
  5937. preferencesShow: function(event){
  5938. if($("#reader_preferences").length){
  5939. return;
  5940. }
  5941.  
  5942. UI._loadBlocker();
  5943.  
  5944. UI.$prefs = $('<div id="reader_preferences">')
  5945. .css('cssText', 'position:fixed; top:12%; left:30%; width:500px; z-index:300000;')
  5946. .append(
  5947. $('<style>').text(Res.preferencesCSS))
  5948. .append(
  5949. $('<div class="body">').html(Res.preferencesHTML))
  5950. .appendTo('body');
  5951.  
  5952. UI.preferencesLoadHandler();
  5953. },
  5954. _loadBlocker: function() {
  5955. UI.$blocker = $('<div>').attr({
  5956. id: 'uil_blocker',
  5957. style: 'position:fixed;top:0px;left:0px;right:0px;bottom:0px;background-color:#000;opacity:0.5;z-index:100000;'
  5958. }).appendTo('body');
  5959. },
  5960. hide: function(){
  5961. if(UI.$prefs) UI.$prefs.remove();
  5962. if(UI.$blocker) UI.$blocker.remove();
  5963. UI.$prefs = null;
  5964. UI.$blocker = null;
  5965. },
  5966. preferencesLoadHandler: function(){
  5967. var $form = $("#preferences");
  5968.  
  5969. // checkbox
  5970. $form.find("#enable-cn2tw").get(0).checked = Setting.cn2tw;
  5971. $form.find("#disable-auto-launch").get(0).checked = Setting.getDisableAutoLaunch();
  5972. $form.find("#booklink-enable").get(0).checked = Setting.booklink_enable;
  5973. $form.find("#debug").get(0).checked = Setting.debug;
  5974. $form.find("#quietMode").get(0).checked = Setting.isQuietMode;
  5975. $form.find("#pic-nightmode-check").get(0).checked = Setting.picNightModeCheck;
  5976. $form.find("#copyCurTitle").get(0).checked = Setting.copyCurTitle;
  5977.  
  5978. $form.find("#hide-menu-list").get(0).checked = Setting.menu_list_hiddden;
  5979. $form.find("#hide-footer-nav").get(0).checked = Setting.hide_footer_nav;
  5980. $form.find("#hide-preferences-button").get(0).checked = Setting.hide_preferences_button;
  5981. $form.find("#add-nextpage-to-history").get(0).checked = Setting.addToHistory;
  5982. $form.find("#enable-dblclick-pause").get(0).checked = Setting.dblclickPause;
  5983.  
  5984. $form.find("#font-family").get(0).value = Setting.font_family;
  5985. $form.find("#font-size").get(0).value = Setting.font_size;
  5986. $form.find("#content_width").get(0).value = Setting.content_width;
  5987. $form.find("#text_line_height").get(0).value = Setting.text_line_height;
  5988. $form.find("#split_content").get(0).checked = Setting.split_content;
  5989. $form.find("#scroll_animate").get(0).checked = Setting.scrollAnimate;
  5990.  
  5991. $form.find("#remain-height").get(0).value = Setting.remain_height;
  5992. $form.find("#extra_css").get(0).value = Setting.extra_css;
  5993. $form.find("#custom_siteinfo").get(0).value = Setting.customSiteinfo;
  5994. UI._rules = $form.find("#custom_replace_rules").get(0).value = Setting.customReplaceRules;
  5995.  
  5996. // 界面语言
  5997. var $lang = $form.find("#lang");
  5998. $("<option>").text("zh-CN").appendTo($lang);
  5999. $("<option>").text("zh-TW").appendTo($lang);
  6000. $lang.val(Setting.lang).change(function(){
  6001. var key = $(this).find("option:selected").text();
  6002. Setting.lang = key;
  6003. });
  6004.  
  6005. // 皮肤
  6006. var $skin = $form.find("#skin");
  6007. for(var key in UI.skins){
  6008. $("<option>").text(key).appendTo($skin);
  6009. }
  6010. $skin.val(Setting.skin_name).change(function(){
  6011. var key = $(this).find("option:selected").text();
  6012. UI.refreshSkinStyle(key);
  6013. Setting.skin_name = key;
  6014. });
  6015.  
  6016. // 字体大小等预览
  6017. var preview = _.debounce(function(){
  6018. switch(this.id){
  6019. case "font-size":
  6020. var contentFontSize = UI.calcContentFontSize(this.value);
  6021. var titleFontSize = UI.calcTitleFontSize(this.value);
  6022. if(titleFontSize) {
  6023. UI.$content.css("font-size", contentFontSize);
  6024. UI.$content.find("h1").css("font-size", titleFontSize);
  6025. }
  6026. break;
  6027. case "font-family":
  6028. UI.$content.css("font-family", this.value);
  6029. break;
  6030. case "content_width":
  6031. UI.$content.css("width", this.value);
  6032. break;
  6033. case "text_line_height":
  6034. UI.$content.css("line-height", this.value);
  6035. break;
  6036. default:
  6037. break;
  6038. }
  6039. }, 300);
  6040. $form.on("input", "input", preview);
  6041.  
  6042. // 初始化设置按键
  6043. $form.find("#quietModeKey").get(0).value = Setting.quietModeKey;
  6044. $form.find("#openPreferencesKey").get(0).value = Setting.openPreferencesKey;
  6045. $form.find("#setHideMenuListKey").get(0).value = Setting.hideMenuListKey;
  6046. $form.find("#setOpenSpeechKey").get(0).value = Setting.openSpeechKey;
  6047.  
  6048. // 点击事件
  6049. $form.on('click', 'input:checkbox, input:button', function(event){
  6050. UI.preferencesClickHandler(event.target);
  6051. });
  6052. },
  6053. cleanPreview: function() {
  6054. UI.$content.find("h1").css("font-size", "");
  6055.  
  6056. // 恢复初始设置(有误操作)
  6057. // UI.$content.removeAttr('style');
  6058. },
  6059. preferencesClickHandler: function(target){
  6060. var key;
  6061. switch (target.id) {
  6062. case 'close_button':
  6063. UI.preferencesCloseHandler();
  6064. break;
  6065. case 'save_button':
  6066. UI.preferencesSaveHandler();
  6067. break;
  6068. case 'debug':
  6069. Setting.debug = !Setting.debug;
  6070. toggleConsole(Setting.debug);
  6071. break;
  6072. case 'quietMode':
  6073. UI.toggleQuietMode(target.checked);
  6074. break;
  6075. case 'hide-menu-list':
  6076. UI.hideMenuList(target.checked);
  6077. break;
  6078. case 'hide-preferences-button':
  6079. UI.hidePreferencesButton(target.checked);
  6080. if (target.checked) {
  6081. alert('隐藏后通过快捷键或 Greasemonkey 用户脚本命令处调用'.uiTrans());
  6082. }
  6083. break;
  6084. case 'hide-footer-nav':
  6085. break;
  6086. case 'quietModeKey':
  6087. key = prompt('请输入打开设置的快捷键:'.uiTrans(), Setting.quietModeKey);
  6088. if (key) {
  6089. Setting.quietModeKey = key;
  6090. $(target).val(key);
  6091. }
  6092. break;
  6093. case 'openPreferencesKey':
  6094. key = prompt('请输入打开设置的快捷键:'.uiTrans(), Setting.openPreferencesKey);
  6095. if (key) {
  6096. Setting.openPreferencesKey = key;
  6097. $(target).val(key);
  6098. }
  6099. break;
  6100. case 'setHideMenuListKey':
  6101. key = prompt('请输入切换左侧章节列表的快捷键:'.uiTrans(), Setting.hideMenuListKey);
  6102. if (key) {
  6103. Setting.hideMenuListKey = key;
  6104. $(target).val(key);
  6105. }
  6106. break;
  6107. case 'setOpenSpeechKey':
  6108. key = prompt('请输入打开朗读的快捷键:'.uiTrans(), Setting.openSpeechKey);
  6109. if (key) {
  6110. Setting.openSpeechKey = key;
  6111. $(target).val(key);
  6112. }
  6113. break;
  6114. case 'saveAsTxt':
  6115. UI.preferencesCloseHandler();
  6116. App.saveAsTxt();
  6117. break;
  6118. case 'speech':
  6119. UI.preferencesCloseHandler();
  6120. bus.$emit(SHOW_SPEECH);
  6121. break;
  6122. default:
  6123. break;
  6124. }
  6125. },
  6126. preferencesCloseHandler: function(){
  6127. UI.cleanPreview();
  6128.  
  6129. UI.hide();
  6130. },
  6131. preferencesSaveHandler: function(){
  6132. var $form = $("#preferences");
  6133.  
  6134. Setting.setDisableAutoLaunch($form.find("#disable-auto-launch").get(0).checked);
  6135.  
  6136. Setting.cn2tw = $form.find("#enable-cn2tw").get(0).checked;
  6137. Setting.booklink_enable = $form.find("#booklink-enable").get(0).checked;
  6138. Setting.isQuietMode = $form.find("#quietMode").get(0).checked;
  6139. Setting.debug = $form.find("#debug").get(0).checked;
  6140. Setting.picNightModeCheck = $form.find("#pic-nightmode-check").get(0).checked;
  6141. Setting.setCopyCurTitle($form.find("#copyCurTitle").get(0).checked);
  6142.  
  6143. Setting.addToHistory = $form.find("#add-nextpage-to-history").get(0).checked;
  6144. Setting.dblclickPause = $form.find("#enable-dblclick-pause").get(0).checked;
  6145.  
  6146. var skinName = $form.find("#skin").find("option:selected").text();
  6147. Setting.skin_name = skinName;
  6148. UI.refreshSkinStyle(skinName);
  6149.  
  6150. Setting.font_family = $form.find("#font-family").get(0).value;
  6151. UI.$content.css("font-family", Setting.font_family);
  6152.  
  6153. Setting.font_size = $form.find("#font-size").get(0).value;
  6154. Setting.text_line_height = $form.find("#text_line_height").get(0).value;
  6155. Setting.content_width = $form.find("#content_width").get(0).value;
  6156. Setting.remain_height = $form.find("#remain-height").get(0).value;
  6157. Setting.split_content = $form.find("#split_content").get(0).checked;
  6158. Setting.scrollAnimate = $form.find("#scroll_animate").get(0).checked;
  6159.  
  6160. Setting.menu_list_hiddden = $form.find("#hide-menu-list").get(0).checked;
  6161. UI.hideMenuList(Setting.menu_list_hiddden);
  6162.  
  6163. Setting.hide_footer_nav = $form.find("#hide-footer-nav").get(0).checked;
  6164. Setting.hide_preferences_button = $form.find("#hide-preferences-button").get(0).checked;
  6165.  
  6166. var css = $form.find("#extra_css").get(0).value;
  6167. UI.refreshExtraStyle(css);
  6168. Setting.extra_css = css;
  6169.  
  6170. Setting.customSiteinfo = $form.find("#custom_siteinfo").get(0).value;
  6171.  
  6172. // 自定义替换规则直接生效
  6173. var rules = $form.find("#custom_replace_rules").get(0).value;
  6174. Setting.customReplaceRules = rules;
  6175. if (rules != UI._rules) {
  6176. var contentHtml = App.oArticles.join('\n');
  6177. if (rules) {
  6178. // 转换规则
  6179. rules = Rule.parseCustomReplaceRules(rules);
  6180. // 替换
  6181. contentHtml = Parser.prototype.replaceHtml(contentHtml, rules);
  6182. }
  6183.  
  6184. UI.$content.html(contentHtml);
  6185.  
  6186. App.resetCache();
  6187.  
  6188. UI._rules = rules;
  6189. }
  6190.  
  6191. // 重新载入样式
  6192. UI.cleanPreview();
  6193. UI.refreshMainStyle();
  6194.  
  6195. UI.hide();
  6196. },
  6197. openHelp: function() {
  6198.  
  6199. },
  6200. notice: function (htmlText, ms){
  6201. var $noticeDiv = $("#alert");
  6202. if (!ms) {
  6203. ms = 1666;
  6204. }
  6205.  
  6206. clearTimeout(UI.noticeDivto);
  6207. $noticeDiv.find("p").html(htmlText);
  6208. $noticeDiv.fadeIn("fast");
  6209.  
  6210. UI.noticeDivto = setTimeout(function(){
  6211. $noticeDiv.fadeOut(500);
  6212. }, ms);
  6213.  
  6214. return $noticeDiv;
  6215. }
  6216. };
  6217.  
  6218. UI.skins["缺省皮肤".uiTrans()] = "";
  6219. UI.skins["暗色皮肤".uiTrans()] = "body { color: #666; background-color: rgba(0;0;0;.1); }\
  6220. .title { color: #222; }";
  6221. UI.skins["白底黑字".uiTrans()] = "body { color: black; background-color: white;}\
  6222. .title { font-weight: bold; border-bottom: 0.1em solid; margin-bottom: 1.857em; padding-bottom: 0.857em;}";
  6223. UI.skins["夜间模式".uiTrans()] = "body { color: #939392; background: #2d2d2d; } #preferencesBtn { background: white; } #mynovelreader-content img { background-color: #c0c0c0; } .chapter.active div{color: #939392;}";
  6224. UI.skins["夜间模式1".uiTrans()] = "body { color: #679; background-color: black; } #preferencesBtn img { background-color: white !important; } .title { color: #3399FF; background-color: #121212; }";
  6225. UI.skins["夜间模式2".uiTrans()] = "body { color: #AAAAAA; background-color: #121212; } #preferencesBtn img { background-color: white; } #mynovelreader-content img { background-color: #c0c0c0; } .title { color: #3399FF; background-color: #121212; } body a { color: #E0BC2D; } body a:link { color: #E0BC2D; } body a:visited { color:#AAAAAA; } body a:hover { color: #3399FF; } body a:active { color: #423F3F; }";
  6226. UI.skins["夜间模式(多看)".uiTrans()] = "body { color: #4A4A4A; background: #101819; } #preferencesBtn { background: white; } #mynovelreader-content img { background-color: #c0c0c0; }";
  6227.  
  6228. UI.skins["橙色背景".uiTrans()] = "body { color: #24272c; background-color: #FEF0E1; }";
  6229. UI.skins["绿色背景".uiTrans()] = "body { color: black; background-color: #d8e2c8; }";
  6230. UI.skins["绿色背景2".uiTrans()] = "body { color: black; background-color: #CCE8CF; }";
  6231. UI.skins["蓝色背景".uiTrans()] = "body { color: black; background-color: #E7F4FE; }";
  6232. UI.skins["棕黄背景".uiTrans()] = "body { color: black; background-color: #C2A886; }";
  6233. UI.skins["经典皮肤".uiTrans()] = "body { color: black; background-color: #EAEAEE; } .title { background-color: #f0f0f0; }";
  6234.  
  6235. UI.skins["起点牛皮纸(深色)".uiTrans()] = "body { color: black; background: url(\"http://qidian.gtimg.com/qd/images/read.qidian.com/theme/body_theme1_bg_2x.0.3.png\"); }";
  6236. UI.skins["起点牛皮纸(浅色)".uiTrans()] = "body { color: black; background: url(\"http://qidian.gtimg.com/qd/images/read.qidian.com/theme/theme_1_bg_2x.0.3.png\"); }";
  6237.  
  6238. var getBooleanConfig = function(configName, defaultValue) {
  6239. var config$$1 = GM_getValue(configName);
  6240. if(config$$1 === undefined) {
  6241. GM_setValue(configName, defaultValue);
  6242. config$$1 = defaultValue;
  6243. }
  6244. return config$$1;
  6245. };
  6246.  
  6247. var Setting = {
  6248. getDisableAutoLaunch: function() { // 强制手动启用模式
  6249. return getBooleanConfig("disable_auto_launch", false);
  6250. },
  6251. setDisableAutoLaunch: function(bool) {
  6252. GM_setValue("disable_auto_launch", bool);
  6253. },
  6254.  
  6255. // 按键调用会遇到问题: Greasemonkey 访问违规:unsafeWindow 无法调用 GM_getValue
  6256. // 故改成这种形式
  6257. copyCurTitle: getBooleanConfig("copyCurTitle", true),
  6258. setCopyCurTitle: function (bool) {
  6259. this.copyCurTitle = !!bool;
  6260. GM_setValue("copyCurTitle", !!bool);
  6261. },
  6262.  
  6263. get cn2tw() {
  6264. if (_.isUndefined(this._cn2tw)) {
  6265. this._cn2tw = getBooleanConfig('cn2tw', this.lang === 'zh-TW' ? true : false);
  6266. }
  6267. return this._cn2tw;
  6268. },
  6269. set cn2tw(bool) {
  6270. GM_setValue('cn2tw', bool);
  6271. this._cn2tw = bool;
  6272. },
  6273.  
  6274. get booklink_enable() { // booklink.me 跳转的自动启动
  6275. return getBooleanConfig("booklink_enable", true);
  6276. },
  6277. set booklink_enable(bool) {
  6278. GM_setValue("booklink_enable", bool);
  6279. },
  6280.  
  6281. get debug() { // 调试
  6282. if (_.isUndefined(this._debug)) {
  6283. this._debug = getBooleanConfig("debug", false);
  6284. }
  6285. return this._debug;
  6286. },
  6287. set debug(bool) {
  6288. this._debug = bool;
  6289. GM_setValue("debug", bool);
  6290. toggleConsole(bool);
  6291. },
  6292.  
  6293. get addToHistory() {
  6294. if (_.isUndefined(this._addToHistory)) {
  6295. this._addToHistory = getBooleanConfig("add_nextpage_to_history", true);
  6296. }
  6297. return this._addToHistory;
  6298. },
  6299. set addToHistory(bool) {
  6300. this._addToHistory = bool;
  6301. GM_setValue("add_nextpage_to_history", bool);
  6302. },
  6303.  
  6304. get dblclickPause() {
  6305. return getBooleanConfig('dblclick_pause', true);
  6306. },
  6307. set dblclickPause(bool) {
  6308. GM_setValue('dblclick_pause', bool);
  6309. },
  6310.  
  6311. get remain_height() { // 距离底部多少高度(px)开始加载下一页
  6312. if(_.isUndefined(this._remain_height)){
  6313. this._remain_height = parseInt(GM_getValue("remain_height"), 10) || 400;
  6314. }
  6315. return this._remain_height;
  6316. },
  6317. set remain_height(val) {
  6318. this._remain_height = val;
  6319. GM_setValue("remain_height", val);
  6320. },
  6321.  
  6322. get lang() {
  6323. if (_.isUndefined(this._lang)) {
  6324. this._lang = GM_getValue("lang") || ((navigator.language === "zh-TW" || navigator.language === "zh-HK") ? "zh-TW" : "zh-CN");
  6325. }
  6326. return this._lang;
  6327. },
  6328. set lang(val) {
  6329. this._lang = val;
  6330. config.lang = val;
  6331. GM_setValue("lang", val);
  6332. },
  6333.  
  6334. get font_family() {
  6335. return GM_getValue("font_family") || "微软雅黑,宋体,黑体,楷体".uiTrans();
  6336. },
  6337. set font_family(val) {
  6338. GM_setValue("font_family", val);
  6339. },
  6340.  
  6341. get font_size() { // 字体大小
  6342. return GM_getValue("font_size") || "18px";
  6343. },
  6344. set font_size(val) {
  6345. GM_setValue("font_size", val);
  6346. },
  6347.  
  6348. get text_line_height(){
  6349. return GM_getValue("text_line_height") || "2em";
  6350. },
  6351. set text_line_height(val){
  6352. GM_setValue("text_line_height", val);
  6353. },
  6354.  
  6355. get content_width() { // 内容宽度
  6356. return GM_getValue("content_width") || "800px";
  6357. },
  6358. set content_width(val) {
  6359. GM_setValue("content_width", val);
  6360. },
  6361.  
  6362. get extra_css() {
  6363. return GM_getValue("extra_css", "");
  6364. },
  6365. set extra_css(val) {
  6366. GM_setValue("extra_css", val);
  6367. },
  6368.  
  6369. get customSiteinfo() {
  6370. return GM_getValue('custom_siteinfo', '[]');
  6371. },
  6372. set customSiteinfo(val) {
  6373. GM_setValue('custom_siteinfo', val);
  6374. },
  6375.  
  6376. get customReplaceRules() {
  6377. var rules = GM_getValue('custom_replace_rules', 'b[āà]ng=棒\n『(.)』=$1');
  6378.  
  6379. return rules;
  6380. },
  6381. set customReplaceRules(val) {
  6382. GM_setValue('custom_replace_rules', val);
  6383. },
  6384.  
  6385. get skin_name() {
  6386. return GM_getValue("skin_name") || "缺省皮肤".uiTrans();
  6387. },
  6388. set skin_name(val) {
  6389. GM_setValue("skin_name", val);
  6390. },
  6391.  
  6392. get menu_list_hiddden() {
  6393. return getBooleanConfig("menu_list_hiddden", false);
  6394. },
  6395. set menu_list_hiddden(bool) {
  6396. GM_setValue("menu_list_hiddden", bool);
  6397. },
  6398.  
  6399. get hide_footer_nav() {
  6400. return getBooleanConfig("hide_footer_nav", true);
  6401. },
  6402. set hide_footer_nav(bool) {
  6403. GM_setValue("hide_footer_nav", bool);
  6404. UI.hideFooterNavStyle(bool);
  6405. },
  6406.  
  6407. get hide_preferences_button() {
  6408. return getBooleanConfig("hide_preferences_button", false);
  6409. },
  6410. set hide_preferences_button(bool) {
  6411. GM_setValue('hide_preferences_button', bool);
  6412. },
  6413.  
  6414. // === 快捷键
  6415.  
  6416. // 安静模式切换快捷键
  6417. get quietModeKey() {
  6418. if (this._quietModeKey) {
  6419. return this._quietModeKey;
  6420. }
  6421. this._quietModeKey = GM_getValue('quietModeKey') || 'q';
  6422.  
  6423. return this._quietModeKey;
  6424. },
  6425. set quietModeKey(keyCode) {
  6426. this._quietModeKey = keyCode;
  6427. GM_setValue('quietModeKey', keyCode);
  6428. },
  6429.  
  6430. // 打开设置窗口的快捷键
  6431. get openPreferencesKey() {
  6432. if (this._openPreferencesKey) {
  6433. return this._openPreferencesKey;
  6434. }
  6435. this._openPreferencesKey = GM_getValue('open_preferences_key') || 's';
  6436.  
  6437. return this._openPreferencesKey;
  6438. },
  6439. set openPreferencesKey(keyCode) {
  6440. this._openPreferencesKey = keyCode;
  6441. GM_setValue('open_preferences_key', keyCode);
  6442. },
  6443.  
  6444. // 隐藏左侧章节列表的快捷键
  6445. get hideMenuListKey() { // 默认为 c
  6446. // 'C'.charCodeAt(0) = 67
  6447. if (this._hideMenuListKey) {
  6448. return this._hideMenuListKey;
  6449. }
  6450. this._hideMenuListKey = GM_getValue('hide_menulist_key') || 'c';
  6451.  
  6452. return this._hideMenuListKey;
  6453. },
  6454. set hideMenuListKey(key) {
  6455. this._hideMenuListKey = key;
  6456. GM_setValue("hide_menulist_key", key);
  6457. },
  6458.  
  6459. // 打开朗读快捷键
  6460. get openSpeechKey() {
  6461. return GM_getValue('openSpeechKey') || 'a';
  6462. },
  6463. set openSpeechKey(key) {
  6464. GM_setValue('openSpeechKey', key);
  6465. },
  6466.  
  6467. get picNightModeCheck() {
  6468. return getBooleanConfig('picNightModeCheck', true);
  6469. },
  6470. set picNightModeCheck(bool) {
  6471. GM_setValue('picNightModeCheck', bool);
  6472. },
  6473.  
  6474. get split_content() {
  6475. if (_.isUndefined(this._split_content)) {
  6476. this._split_content = GM_getValue('split_content', true);
  6477. }
  6478. return this._split_content;
  6479. },
  6480. set split_content(bool) {
  6481. this._split_content = bool;
  6482. GM_setValue('split_content', bool);
  6483. },
  6484.  
  6485. get scrollAnimate() {
  6486. return GM_getValue('scrollAnimate', false);
  6487. },
  6488. set scrollAnimate(bool) {
  6489. GM_setValue('scrollAnimate', bool);
  6490. },
  6491. };
  6492.  
  6493. var BookLinkMe = {
  6494. clickedColor: "666666",
  6495.  
  6496. init: function() {
  6497.  
  6498. this.addUnreadButton();
  6499.  
  6500. // if (location.pathname.indexOf("/book-") === 0) {
  6501. // this.chapterPageAddTiebaLink();
  6502. // }
  6503. },
  6504. addUnreadButton: function(){ // 添加一键打开所有未读链接
  6505. var $parent = $('td[colspan="2"]:contains("未读"):first, td[colspan="2"]:contains("未讀"):first');
  6506. if(!$parent.length) return;
  6507.  
  6508. var openAllUnreadLinks = async function(event){
  6509. event.preventDefault();
  6510.  
  6511. var links = $x('./ancestor::table[@width="100%"]/descendant::a[img[@alt="未读"]]', event.target);
  6512. for (let link of links) {
  6513. // 忽略没有盗版的
  6514. let chapterLink = link.parentNode.nextSibling.nextSibling.querySelector('a');
  6515. if (chapterLink.querySelector('font[color*="800000"]')) {
  6516. continue;
  6517. }
  6518.  
  6519. await delay(200);
  6520.  
  6521. if(isFirefox)
  6522. link.click();
  6523. else
  6524. GM_openInTab(link.href);
  6525.  
  6526. // 设置点击后的样式
  6527. // 未读左边的 1x 链接
  6528. link.parentNode.previousSibling.querySelector('font')
  6529. .setAttribute('color', BookLinkMe.clickedColor);
  6530. chapterLink.classList.add('mclicked');
  6531. }
  6532. };
  6533.  
  6534.  
  6535. $('<a>')
  6536. .attr({ href: 'javascript:;', title: '一键打开所有未读链接', style: 'width:auto;' })
  6537. .click(openAllUnreadLinks)
  6538. .append($('<img src="me.png" style="max-width: 20px;">'))
  6539. .appendTo($parent);
  6540. },
  6541. chapterPageAddTiebaLink: function() {
  6542. var link = $('font:contains("贴吧")').parent().get(0);
  6543. if (!link) return;
  6544.  
  6545. var tiebaUrl = 'http://tieba.baidu.com/f?kw=' + $('h1').text();
  6546. console.log('GM_xmlhttpRequest', tiebaUrl);
  6547. GM_xmlhttpRequest({
  6548. method: "GET",
  6549. url: tiebaUrl,
  6550. onload: function(response) {
  6551. var doc = parseHTML(response.responseText);
  6552. BookLinkMe.load(doc);
  6553. }
  6554. });
  6555. },
  6556. load: function(doc) {
  6557. var $data = $(doc).find('.threadlist_text > a').map(function() {
  6558. return {
  6559. title: $(this).text(),
  6560. url: 'http://tieba.baidu.com' + $(this).attr('href')
  6561. }
  6562. });
  6563.  
  6564. var trimTitle = function(title, strict) {
  6565. title = title.trim()
  6566. .replace(/\.\.\.$/, '');
  6567.  
  6568. if (strict) {
  6569. title = title.replace(/第.*?章\s*/, '');
  6570. }
  6571.  
  6572. // if (toNum) {
  6573. // title = title.replace(/[零一二三四五六七八九十百千万亿]+/, cnNum2ArabNum);
  6574. // }
  6575.  
  6576. return title;
  6577. };
  6578.  
  6579. var findUrl = function(sTitle) {
  6580. if (!sTitle) return;
  6581.  
  6582. var url;
  6583. $data.each(function(i, item) {
  6584. var tiebaTitle = item.title;
  6585. if (tiebaTitle.indexOf(trimTitle(sTitle)) > 0 ||
  6586. sTitle.indexOf(trimTitle(tiebaTitle, true)) > 0 // 包含贴吧标题的部分
  6587. ) {
  6588. url = item.url;
  6589. return true;
  6590. }
  6591. });
  6592.  
  6593. return url;
  6594. };
  6595.  
  6596. $('a:contains("搜索本章节")').each(function(){
  6597. var $this = $(this),
  6598. $thisLine = $this.parent().parent(),
  6599. chapterTitle = $thisLine.prev().find('a[href^="/jump.php"]:first').text();
  6600.  
  6601. var url = findUrl(chapterTitle);
  6602. if (url) {
  6603. $('<a>')
  6604. .attr({ target: '_blank', href: url })
  6605. .text('贴吧')
  6606. .appendTo($this.parent());
  6607. }
  6608. });
  6609. }
  6610. };
  6611.  
  6612. toggleConsole(Setting.debug);
  6613.  
  6614. if (location.host.indexOf('booklink.me') > -1) {
  6615. BookLinkMe.init();
  6616. } else {
  6617. App.init();
  6618. }
  6619.  
  6620. }(Vue));