Greasy Fork is available in English.

My Novel Reader

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

Pada tanggal 06 Maret 2015. Lihat %(latest_version_link).

  1. // ==UserScript==
  2. // @id mynovelreader@ywzhaiqi@gmail.com
  3. // @name My Novel Reader
  4. // @name:zh-CN 小说阅读脚本
  5. // @version 5.0.1
  6. // @namespace https://github.com/ywzhaiqi
  7. // @author ywzhaiqi
  8. // @contributor Roger Au, shyangs, JixunMoe
  9. // @description 小说阅读脚本,统一阅读样式,内容去广告、修正拼音字、段落整理,自动下一页
  10. // @description:zh-CN 小说阅读脚本,统一阅读样式,内容去广告、修正拼音字、段落整理,自动下一页
  11. // @license GPL version 3
  12. // @grant GM_xmlhttpRequest
  13. // @grant GM_addStyle
  14. // @grant GM_getValue
  15. // @grant GM_setValue
  16. // @grant GM_getResourceURL
  17. // @grant GM_openInTab
  18. // @grant GM_setClipboard
  19. // @grant GM_registerMenuCommand
  20. // @grant unsafeWindow
  21. // @homepageURL https://greasyfork.org/scripts/292/
  22. // @require http://cdn.staticfile.org/jquery/2.1.1/jquery.min.js
  23. // @require http://cdn.staticfile.org/underscore.js/1.7.0/underscore-min.js
  24. // @require http://cdn.staticfile.org/keymaster/1.6.1/keymaster.min.js
  25. // @require https://greasyfork.org/scripts/2672-meihua-cn2tw/code/Meihua_cn2tw.js?version=7375
  26. // @resource fontawesomeWoff http://libs.baidu.com/fontawesome/4.0.3/fonts/fontawesome-webfont.woff?v=4.0.3
  27.  
  28. // @include http://read.qidian.com/*,*.aspx
  29. // @include http://readbook.qidian.com/bookreader/*,*.html
  30. // @include http://wwwploy.qidian.com/BookReader/*,*.aspx
  31. // @include http://free.qidian.com/Free/ReadChapter.aspx?*
  32. // @include http://www.qdmm.com/BookReader/*,*.aspx
  33. // @include http://www.qdwenxue.com/BookReader/*,*.aspx
  34. // @include http://chuangshi.qq.com/read/bookreader/*.html
  35. // @include http://chuangshi.qq.com/*bk/*/*.html
  36. // @include http://yunqi.qq.com/*bk/*/*.html
  37. // @include http://dushu.qq.com/read.html?bid=*
  38. // @include http://www.jjwxc.net/onebook.php?novelid=*
  39. // @include http://book.zongheng.com/chapter/*/*.html
  40. // @include http://www.xxsy.net/books/*/*.html
  41. // @include http://book.zhulang.com/*/*.html
  42. // @include http://www.17k.com/chapter/*/*.html
  43. // @include http://mm.17k.com/chapter/*/*.html
  44. // @include http://www.kanxia.net/k/*/*/*.html
  45. // @include http://www.qingdi.com/files/article/html/*/*/*.html
  46. // @include http://www.xkzw.org/*/*.html
  47. // @include http://shouda8.com/*/*.html
  48. // @include http://novel.hongxiu.com/*/*/*.shtml
  49. // @include http://www.readnovel.com/novel/*.html
  50. // http://www.tianyabook.com/*/*.htm
  51.  
  52. // @include http://tieba.baidu.com/p/*
  53. // @include http://booklink.me/*
  54.  
  55. // booklink.me
  56. // @include http://www.shumilou.com/*/*.html
  57. // @include http://www.wcxiaoshuo.com/wcxs-*-*/
  58. // @include http://www.xiaoshuoz.com/wcxs-*-*/
  59. // @include http://www.quledu.com/wcxs-*-*/
  60. // @include http://www.ranwen.cc/*/*/*/*.html
  61. // @include http://www.ranwen.net/files/article/*/*/*.html
  62. // @include http://www.64mi.com/*/*/*/*.html
  63. // @include http://www.bxs.cc/*/*.html*
  64. // @include http://www.laishuwu.com/html/*/*/*.html
  65. // @include http://www.binhuo.com/html/*/*/*.html
  66. // @include http://www.haoqi99.com/haoqi99/*/*/*.shtml
  67. // @include http://www.shuhe.cc/*/*/
  68. // @include http://www.dudukan.net/html/*/*/*.html
  69. // @include http://www.hahawx.com/*/*/*.htm
  70. // @include http://www.zhuzhudao.com/txt/*/*/
  71. // @include http://www.zhuzhudao.cc/txt/*/*/
  72. // @include http://www.dahaomen.net/txt/*/*/
  73. // @include http://www.tadu.com/book/*/*/
  74. // @include http://www.aishoucang.com/*/*.html
  75. // @include http://www.wanshuba.com/Html/*/*/*.html
  76. // @include http://www.zhuishu.net/files/article/html/*/*/*.html
  77. // @include http://www.sqsxs.com/*/*/*.html
  78. // @include http://www.caiwei.tw/html/*/*.html
  79. // @include http://www.hotsk.com/Html/Book/*/*/*.shtml
  80. // @include http://www.92to.com/*/*/*.html
  81. // @include http://www.qirexs.com/read-*-chapter-*.html
  82. // @include http://www.du00.com/read/*/*/*.html
  83. // @include http://www.qishuwu.com/*/*/
  84. // @include http://www.wandoou.com/book/*/*.html
  85. // @include http://www.6yzw.org/*/*.html
  86. // @include http://www.6yzw.com/*/*.html
  87. // @include http://www.daomengren.com/*/*.html
  88. // @include http://muyuge.com/*/*.html
  89. // @include http://www.muyuge.net/*/*.html
  90. // @include http://bbs.vyming.com/novel-read-*-*.html
  91. // @include http://www.9imw.com/novel-read-*-*.html
  92. // @include http://www.23zw.com/olread/*/*/*.html
  93. // @include http://www.50zw.com/book_*/*.html
  94. // @include http://www.xiangcunxiaoshuo.com/shu/*/*.html
  95. // @include http://www.lwxs520.com/books/*/*/*.html
  96. // @include http://www.zashu.net/books/*/*/*.html
  97. // @include http://www.piaotian.net/html/*/*/*.html
  98. // @include http://www.yunlaige.com/html/*/*/*.html
  99. // @include http://www.cfwx.net/files/article/html/*/*/*.html
  100. // @include http://www.qiuwu.net/html/*/*/*.html
  101. // @include http://www.xs84.com/*_*/*
  102. // @include http://www.geiliwx.com/GeiLi/*/*/*.shtml*
  103. // @include http://www.123yq.com/read/*/*/*.shtml
  104.  
  105. // www.sodu.so
  106. // @include http://www.jiaodu8.com/*/*/*/*.html
  107. // @include http://www.fktxt.com/book/*/*.html
  108. // @include http://www.186s.cn/files/article/html/*/*/*.html
  109. // @include http://www.6xs.cn/xs/*/*/*.html
  110. // @include http://www.chaojiqiangbing.com/book/*/*/*.html
  111. // @include http://book.moka123.com/book/*/*/*.html
  112. // @include http://www.suimeng.com/files/article/html/*/*/*.html
  113. // @include http://www.hao662.com/haoshu/*/*/*.html
  114.  
  115. //www.verydu.net
  116. // http://www.yawen8.com/*/*/*.html
  117. // @include http://www.tsxs.cc/files/article/html/*/*/*.html
  118. // @include http://www.ziyuge.com/*/*/*/*/*.html
  119.  
  120. // 其它网站
  121. // @include http://book.sfacg.com/Novel/*/*/*/
  122. // @include http://www.7dsw.com/book/*/*/*.html
  123. // @include http://www.d586.com/*/*/
  124. // @include http://www.bookgew.com/Html/Book/*/*/*.htm
  125. // @include http://read.shuhaha.com/Html/Book/*/*/*.html
  126. // @include http://www.shuhaha.com/Html/Book/*/*/*.html
  127. // @include http://www.biqi.me/files/article/html/*/*/*.html
  128. // @include http://www.ttzw.com/book/*/*.html
  129. // @include http://www.uukanshu.com/*/*/*.html
  130. // @include http://www.173ed.com/read/*/*.html
  131. // @include http://www.a240.com/read/*/*.html
  132. // @include http://www.zhuishu.com/*/*.html
  133. // @include http://www.shuangde.cc/*/*.html
  134. // @include http://www.shenmaxiaoshuo.com/ml-*-*/
  135. // @include http://www.86kankan.com/read/*/*.html
  136. // @include http://www.fkzww.com/*/*/*.html
  137. // @include http://www.151kan.com/*/*/*/*.html
  138. // @include http://www.bookabc.net/*/*/*.html
  139. // @include http://www.xshuotxt.com/*/*/*/*.html
  140. // @include http://www.doulaidu.com/*/*/*.html
  141. // @include http://www.d586.com/*/*/
  142. // @include http://www.kanshu.la/book/*/*.shtml
  143. // @include http://www.wtcxs.com/files/article/html/*/*/*.html
  144. // @include http://www.5du5.com/book/*/*/*.html
  145. // @include http://book.kanunu.org/*/*/*.html
  146. // @include http://www.kanunu8.com/book4/*/*.html
  147. // @include http://paitxt.com/*/*/*.html
  148. // @include http://www.shunong.com/yuedu/*/*/*.html
  149. // @include http://book.yayacms.com/*/book_*_*.html
  150. // @include http://www.yqhhy.cc/*/*/*.html
  151. // @include http://www.nuoqiu.com/static/*/*.html
  152. // @include http://www.17yue.com/*/*/*.html
  153. // @include http://dukeba.com/book/*/*/*.shtml
  154. // @include http://www.wenchangshuyuan.com/html/*/*/*.html
  155. // @include http://www.pofeng.net/xiaoshuo/*/*.html
  156. // @include http://www.epzww.com/book/*/*
  157. // @include http://tw.xiaoshuokan.com/haokan/*/*.html
  158. // @include http://www.wobudu.com/*/*.html
  159. // @include http://www.qb5.com/xiaoshuo/*/*/*.html
  160. // @include http://www.23us.com/html/*/*/*.html
  161. // @include http://www.23wx.com/html/*/*/*.html
  162. // @include http://www.xs222.com/html/*/*/*.html
  163. // @include http://www.bixiage.com/*/*/*/*.html
  164. // @include http://www.ranwenxiaoshuo.com/files/article/html/*/*/*.html
  165. // @include http://www.ranwenxiaoshuo.com/*/*-*-*.html
  166. // @include http://www.bjxiaoshuo.com/bjxs-*-*/
  167. // @include http://www.59shuku.com/xiaoshuo/*/*.htm
  168. // @include http://www.16kbook.org/Html/Book/*/*/*.shtml
  169. // @include http://www.dixiaoshuo.com/Html/*/*.html
  170. // @include http://www.nieshu.com/Book/*/*/*.shtml
  171. // @include http://www.tlxsw.com/files/article/html/*/*/*.html
  172. // @include http://www.1kanshu.com/files/article/html/*/*/*.html
  173. // @include http://www.uutxt.org/book/*/*/*.html
  174. // @include http://www.5800.cc/*/*/*/*.html
  175. // @include http://www.biquge.com/*/*.html
  176. // @include http://www.qududu.com/book/*/*/*.html
  177. // @include http://www.free97.cn/book/*/*/*.html
  178. // @include http://www.122s.com/book/*/*.html
  179. // @include http://www.123du.net/dudu-*/*/*.html
  180. // @include http://www.123du.cc/dudu-*/*/*.html
  181. // @include http://www.123du.net/book/*/*.html
  182. // @include http://www.hwafa.com/*/*.html
  183. // @include http://www.qmshu.com/html/*/*/*.html
  184. // @include http://dlzw.cc/article-*-*.html
  185. // @include http://www.shushu5.com/read/*/*.html
  186. // @include http://www.xiaoyanwenxue.com/files/article/html/*/*/*.html
  187. // @include http://www.3gsc.com.cn/bookcon/*_*_*
  188. // @include http://www.bj-ibook.cn/book/*/*/*.htm
  189. // @include http://www.baoliny.com/*/*.html
  190. // @include http://www.dajiadu.net/files/article/html/*/*/*.html
  191. // @include http://www.yankuai.com/files/article/html/*/*/*.html
  192. // @include http://www.docin.net/*/*.html
  193. // @include http://www.dushuge.net/html/*/*/*.html
  194. // @include http://www.xunshu.org/xunshu/*/*/*.html
  195. // @include http://www.moneyren.com/book/*/*/*.shtml
  196. // @include http://wemaxfilipino.com/*/*/*.html
  197. // @include http://www.85618892.cn/xiaoshuo/*/*/*.shtml
  198. // @include http://www.bookba.net/Html/Book/*/*/*.html
  199. // @include http://www.moksos.com/*/*/*.html
  200. // @include http://dudu8.net/novel/*/*/*.html
  201. // @include http://www.dawenxue.net/html/*/*/*.html
  202. // @include http://www.yanmoxuan.org/book/*/*/*.html
  203. // @include http://www.duyidu.com/xiaoshuo/*/*/*.html
  204. // @include http://www.69zw.com/xiaoshuo/*/*/*.html
  205. // @include http://www.kan7.com/xiaoshuo/*/*/*.html
  206. // @include http://www.laishu.com/book/*/*/*.shtml
  207. // @include http://www.bxwx.org/b/*/*/*.html
  208. // @include http://www.bxzw.org/*/*/*/*.shtml
  209. // @include http://www.360118.com/html/*/*/*.html
  210. // @include http://www.59to.com/files/article/xiaoshuo/*/*/*.html
  211. // @include http://www.dyzww.com/cn/*/*/*.html
  212. // @include http://www.9wh.net/*/*/*.html
  213. // @include http://www.luoqiu.net/html/*/*/*.html
  214. // @include http://www.luoqiu.com/html/*/*/*.html
  215. // @include http://www.epzw.com/files/article/html/*/*/*.html
  216. // @include http://www.dashubao.com/book/*/*/*.html
  217. // @include http://b.faloo.com/p/*/*.html
  218. // @include http://www.baikv.com/*/*.html
  219. // @include http://www.66721.com/*/*/*.html
  220. // @include http://www.3dllc.com/html/*/*/*.html
  221. // @include http://www.xstxt.com/*/*/
  222. // @include http://www.zzzcn.com/3z*/*/
  223. // @include http://www.zzzcn.com/modules/article/App.php*
  224. // @include http://www.nilongdao.com/book/*/*/*.html
  225. // @include http://xs321.net/*/*/
  226. // @include http://read.guanhuaju.com/files/article/html/*/*/*.html
  227. // @include http://www.book108.com/*/*/*.html
  228. // @include http://5ycn.com/*/*/*.html
  229. // @include http://www.zhaoxiaoshuo.com/chapter-*-*-*/
  230. // @include http://*zbzw.com/*/*.html
  231. // @include http://manghuangji.cc/*/*.html
  232. // @include http://www.aiqis.com/*/*.html
  233. // @include http://www.fftxt.net/book/*/*.html
  234. // @include http://www.5kwx.com/book/*/*/*.html
  235. // @include http://www.uuxiaoshuo.net/html/*/*/*.html
  236. // @include http://www.sanyyo.org/*.html
  237. // @include http://www.chinaisbn.com/*/*/*.html
  238. // @include http://www.caihongwenxue.com/Html/Book/*/*/*.html
  239. // @include http://www.shushuw.cn/shu/*/*.html
  240. // @include http://www.78xs.com/article/*/*/*.shtml
  241. // @include http://www.miaobige.com/*/*/*.html
  242. // @include http://www.woaixiaoshuo.com/xiaoshuo/*/*/*.html
  243. // @include http://www.ty2016.com/book/*/*.html
  244. // @include http://wx.ty2016.com/*/*/*.html
  245. // @include http://www.my285.com/*/*/*/*.htm
  246. // @include http://www.5858xs.com/html/*/*/*.html
  247. // @include http://book.58xs.com/html/*/*/*.html
  248. // @include http://book.mihua.net/*/*/*/*.html
  249. // @include http://www.hjwzw.com/Book/Read/*,*
  250. // @include http://www.365essay.com/*/*.htm
  251. // @include http://www.gengxin8.com/read/*/*.html
  252. // @include http://www.365xs.org/books/*/*/*.html
  253.  
  254. // @exclude */List.htm
  255. // @exclude */List.html
  256. // @exclude */List.shtml
  257. // @exclude */index.htm
  258. // @exclude */index.html
  259. // @exclude */index.shtml
  260. // @exclude */Default.htm
  261. // @exclude */Default.html
  262. // @exclude */Default.shtml
  263.  
  264. // @run-at document-end
  265. // ==/UserScript==
  266.  
  267.  
  268. var isChrome = !!window.chrome;
  269. var isFirefox = navigator.userAgent.indexOf("Firefox") != -1;
  270.  
  271. // 其它设置
  272. var config = {
  273. soduso: false, // www.sodu.so 跳转
  274. content_replacements: true, // 小说屏蔽字修复
  275. fixImageFloats: true, // 图片居中修正
  276. paragraphBlank: true, // 统一段落开头的空格为 2个全角空格
  277. end_color: "#666666", // 最后一页的链接颜色
  278. PRELOADER: true, // 提前预读下一页
  279. };
  280.  
  281. var READER_AJAX = "reader-ajax"; // 内容需要 ajax 的 className
  282.  
  283.  
  284. // ===== 自动尝试的规则 =====
  285. var Rule = {
  286. titleRegExp: /第?\s*[一二两三四五六七八九十○零百千万亿0-91234567890]{1,6}\s*[章回卷节折篇幕集]/i,
  287. titleReplace: /^章节目录|^文章正文|^正文|全文免费阅读|最新章节|\(文\)/,
  288.  
  289. // nextRegExp: /[上前下后][一]?[页张个篇章节步]/,
  290. nextSelector: "a[rel='next'], a:contains('下一页'), a:contains('下一章'), a:contains('下一节'), a:contains('下页')",
  291. prevSelector: "a[rel='prev'], a:contains('上一页'), a:contains('上一章'), a:contains('上一节'), a:contains('上页')",
  292. // 忽略的下一页链接,匹配 href
  293. nextUrlIgnore: [
  294. /(?:(?:index|list|last|LastPage|end)\.)|BuyChapterUnLogin|BookReader\/vip,|^javascript:/i,
  295. /free\.qidian\.com\/Free\/ShowBook\.aspx\?bookid=/i,
  296. /book\.zongheng\.com\/readmore/i,
  297. /www\.shumilou\.com\/to-n-[a-z]+-\d+\.html/i,
  298. /read\.qidian\.com\/BookReader\/\d+,0\.aspx$/i,
  299. /\/0\.html$/i,
  300. ],
  301. nextUrlCompare: /\/\d+(_\d+)?\.html?$|\/wcxs-\d+-\d+\/$|chapter-\d+\.html$/i, // 忽略的下一页链接(特殊),跟上一页比较
  302.  
  303. // 按顺序匹配,匹配到则停止。econtains 完全相等
  304. indexSelectors: ["a[href='index.html']", "a:contains('返回书目')", "a:contains('章节目录')", "a:contains('章节列表')",
  305. "a:econtains('最新章节')", "a:contains('回目录')","a:contains('回书目')", "a:contains('目 录')", "a:contains('目录')"],
  306.  
  307. contentSelectors: ["#pagecontent", "#contentbox", "#bmsy_content", "#bookpartinfo", "#htmlContent",
  308. "#text_area", "#chapter_content", "#chapterContent", "#partbody",
  309. "#article_content", "#BookTextRead", "#booktext", "#BookText", "#readtext", "#text_c", "#txt_td", "#TXT", "#txt", "#zjneirong",
  310. ".novel_content", ".readmain_inner", ".noveltext", ".booktext",
  311. "#contentTxt", "#oldtext", "#a_content", "#contents", "#content2", "#contentts", "#content", ".content"],
  312.  
  313. // (测试)尝试查找书名。顶部章节导航的最后一个链接可能是书名。
  314. bookTitleSelector: ".h1title > .shuming > a[title], .chapter_nav > div:first > a:last",
  315.  
  316. contentRemove: "script, iframe", // 内容移除选择器
  317. contentReplace: /'ads_wz_txt;',|最新.?章节|百度搜索|无弹窗小说网|更新快无弹窗纯文字|高品质更新|小说章节更新最快|\(百度搜.\)|全文字手打|“” 看|无.弹.窗.小.说.网|追书网|〖∷∷无弹窗∷纯文字∷ 〗/g,
  318. removeLineRegExp: /<p>[ \s。;,!\.∷〖]*<\/p>/g, // 移除只有一个字符的行
  319.  
  320. // 以下不常改
  321. replaceBrs: /(<br[^>]*>[ \n\r\t]*){1,}/gi, // 替换为<p>
  322. };
  323.  
  324. // ===== 自定义站点规则 =====
  325. Rule.specialSite = [
  326. // 详细版规则示例。注:该网站已无法访问。
  327. {siteName: "泡书吧", // 站点名字... (可选)
  328. url: "^http://www\\.paoshu8\\.net/Html/\\S+\\.shtm$", // // 站点正则... (~~必须~~)
  329.  
  330. // 获取标题
  331. titleReg: /(.*?)最新章节 [-_\\\/](.*?)[-_\/].*/, // 书籍标题、章节标题正则 (可选)
  332. titlePos: 0, // 书籍标题位置:0 或 1 (可选,默认为 0)
  333. titleSelector: "#title h1",
  334.  
  335. indexSelector: "a:contains('回目录')", // 首页链接 jQuery 选择器 (不填则尝试自动搜索)
  336. prevSelector: "a:contains('翻上页')", // 上一页链接 jQuery 选择器 (不填则尝试自动搜索)
  337. nextSelector: "a:contains('翻下页')", // 下一页链接 jQuery 选择器 (不填则尝试自动搜索)
  338.  
  339. // 获取内容
  340. contentSelector: "#BookText", // 内容 jQuery 选择器 (不填则尝试自动搜索)
  341. useiframe: false, // (可选)下一页加载是否使用 iframe
  342. // mutationSelector: "#chaptercontainer", // (可选)内容生成监视器
  343. // 对内容的处理
  344. contentHandle: false, // (可选)是否对内容进行特殊处理,诸如拼音字修复等,诸如起点等网站可禁用
  345. fixImage: true, // (可选),图片居中,不分大小
  346. contentReplace: /(\*W|(w|\(w).{10,25}(吧\*|)|\))|看小说就上|本书首发|泡.{1,6}吧|百度搜索阅读最新最全的小说|http:\/\/www.paoshu8.com\/|无弹窗/g, // 需要移除的内容正则 (可选)
  347. contentPatch: function(fakeStub){ // (可选)内容补丁。解决翻页是脚本的情况
  348. var $next = fakeStub.find('#LinkMenu');
  349. $next.html($next.html().replace(/<script>ShowLinkMenu.*?(<a.*?a>).*?(<a.*?a>).*?script>/,'$1$2') +
  350. '<a href=\'List.shtm\'>回目录</a>');
  351. }
  352. },
  353. // 特殊站点,需再次获取且跨域。添加 class="reader-ajax",同时需要 src, charset
  354. {siteName: "起点中文、起点女生、起点文学",
  355. url: "^http://(www|read|readbook|wwwploy)\\.(qidian|qdmm|qdwenxue)\\.com/BookReader/.*",
  356. // titleReg: "小说:(.*?)(?:独家首发)/(.*?)/.*",
  357. titleSelector: "#lbChapterName",
  358. bookTitleSelector: ".page_site > a:last",
  359. // contentSelector: "#hdContent",
  360. nextUrl: function($doc){ // 为了避免起点某次改版后把1页拆成2页,然后造成重复载入第一页的情况
  361. var html = $doc.find('script:contains(nextpage=)').html();
  362. if (!html) return;
  363. var m = html.match(/nextpage='(.*?)'/);
  364. if (m) return m[1];
  365. },
  366. prevUrl: function($doc){
  367. var html = $doc.find('script:contains(prevpage=)').html();
  368. if (!html) return;
  369. var m = html.match(/prevpage='(.*?)'/);
  370. if (m) return m[1];
  371. },
  372. contentReplace: {
  373. "\\[img=(.*)\\]": "<p><img src='$1'></p><p>",
  374. "\\[+CP.*(http://file.*\\.jpg)\\]+": "<p><img src='$1'></p><p>",
  375. "\\[bookid=(\\d+),bookname=(.*?)\\]": "<a href='http://www.qidian.com/Book/$1.aspx'>$2</a>",
  376. "www.cmfu.com发布|起点中文网www.qidian.com欢迎广大书友光临阅读.*": "",
  377. '(<p>\\s+)?<a href="?http://www.(?:qidian|cmfu).com"?>起点中文网.*': '',
  378.  
  379. '([\\u4e00-\\u9fa5])[%¥]+([\\u4e00-\\u9fa5])': '$1$2', // 屏蔽词修正,例如:风%%骚
  380. },
  381. contentRemove: "span[id^='ad_']",
  382. contentPatch: function(fakeStub){
  383. fakeStub.find('#maincontent script[src$=".txt"]').addClass('reader-ajax');
  384. },
  385. },
  386. {siteName: "起点中文网免费频道",
  387. url: "^http://free\\.qidian\\.com/Free/ReadChapter\\.aspx",
  388. titleSelector: ".title > h3",
  389. bookTitleSelector: ".site_rect > a:last",
  390. contentSelector: "#chapter_cont, #content",
  391. contentRemove: ".nice_books",
  392. contentReplace: {
  393. "\\[img=(.*)\\]": "<p><img src='$1'></p><p>",
  394. "\\[+CP.*(http://file.*\\.jpg)\\]+": "<p><img src='$1'></p><p>",
  395. "\\[bookid=(\\d+),bookname=(.*?)\\]": "<a href='http://www.qidian.com/Book/$1.aspx'>$2</a>",
  396. "www.cmfu.com发布|起点中文网www.qidian.com欢迎广大书友光临阅读.*": "",
  397. '(<p>\\s+)?<a href="?http://www.(?:qidian|cmfu).com"?>起点中文网.*': ''
  398. },
  399. contentPatch: function(fakeStub) {
  400. fakeStub.find('#chapter_cont, #content > script:first').addClass('reader-ajax');
  401. }
  402. },
  403. {siteName: "纵横中文网",
  404. url: "^http://book\\.zongheng\\.com/\\S+\\/\\d+\\.html$",
  405. contentHandle: false,
  406. // titleReg: "(.*?)-(.*)",
  407. titleSelector: "em[itemprop='headline']",
  408. bookTitleSelector: ".nav>a:last",
  409. contentPatch: function(fakeStub){
  410. fakeStub.find('.watermark').remove();
  411. // 给第几章添加空格
  412. var chapterTitle = fakeStub.find(".tc > h2").text();
  413. var chapterTitle1 = fakeStub.find(".tc > h2 em").text();
  414. if(chapterTitle1) {
  415. chapterTitle = chapterTitle.replace(chapterTitle1, " ") + chapterTitle1;
  416. }
  417. fakeStub.find("title").text(
  418. fakeStub.find(".tc > h1").text() + "-" + chapterTitle);
  419. }
  420. },
  421. {siteName: "创世中文网",
  422. url: "^http://(?:chuangshi|yunqi)\\.qq\\.com/|^http://dushu\\.qq\\.com/read.html\\?bid=",
  423. titleReg: "(.*?)_(.*)_创世中文",
  424.  
  425. nextSelector: '#rightFloatBar_nextChapterBtn',
  426. prevSelector: '#rightFloatBar_preChapterBtn',
  427. indexSelector: '',
  428.  
  429. contentSelector: ".bookreadercontent",
  430. // contentSelector: "#chaptercontainer",
  431. contentHandle: false,
  432. useiframe: true,
  433. mutationSelector: "#chaptercontainer", // 内容生成监视器
  434. mutationChildCount: 1,
  435. timeout: 500,
  436. contentRemove: '> p:last',
  437. // contentPatch: function(fakeStub){
  438. // var $body = fakeStub.find('body');
  439. // html = $body.html(),
  440. // novel_showid = unsafeWindow.novel_showid,
  441. // _main = unsafeWindow.CS.page.bookReader.main;
  442.  
  443. // var m = html.match(/uuid\s*=\s*["'](\d+)["']/i);
  444. // if (!m) {
  445. // console.error('无法找到 uuid', html);
  446. // return;
  447. // }
  448. // var uuid = m[1];
  449.  
  450. // var preChapterInfo = _main.getPreChapterInfo(uuid),
  451. // nextChapterInfo = _main.getNextChapterInfo(uuid);
  452. // _pre_uuid = preChapterInfo ? preChapterInfo['uuid'] : 0;
  453. // _next_uuid = nextChapterInfo ? nextChapterInfo['uuid'] : 0;
  454.  
  455. // 上下页
  456. // $('<a rel="prev">').attr('href', _getReadPageUrl(_pre_uuid)).prependTo($body);
  457. // $('<a rel="next">').attr('href', _getReadPageUrl(_next_uuid)).prependTo($body);
  458.  
  459. // // 内容
  460. // var durl = 'http://chuangshi.qq.com/index.php/Bookreader/' + novel_showid +'/' + uuid;
  461. // fakeStub.find('body').append('<div id="content"></div>');
  462. // fakeStub.find('div#content').attr({
  463. // class: 'reader-ajax',
  464. // src: durl,
  465. // charset: 'GB2312'
  466. // });
  467.  
  468. // function _getReadPageUrl(uuid) {
  469. // if (!uuid) return 'javascript:;';
  470. // return window.location.href.replace(/(\d)+\.html/, uuid + '.html');
  471. // }
  472. // },
  473. },
  474. {siteName: "晋江文学网",
  475. url: /^http:\/\/www\.jjwxc\.net\/onebook\.php\S*/,
  476. titleReg: /《(.*?)》.*ˇ(.*?)ˇ.*/,
  477. indexSelector: ".noveltitle > h1 > a",
  478. contentSelector: '.noveltext',
  479. contentHandle: false,
  480. contentRemove: 'font[color], hr',
  481. contentPatch: function(fakeStub){
  482. fakeStub.find('h2').remove();
  483. fakeStub.find('#six_list, #sendKingTickets').parent().remove();
  484. fakeStub.find("div.noveltext").find("div:first, h1, div[style]:last").remove();
  485. }
  486. },
  487. {siteName: "潇湘书院",
  488. url: "^http://www\\.xxsy\\.net/books/.*\\.html",
  489. titleReg: "(.*?) (.*)",
  490. contentSelector: "#zjcontentdiv",
  491. nextSelector: "a[title='阅读下一章节']",
  492. contentHandle: false,
  493. contentReplace: "本书由潇湘书院首发,请勿转载!",
  494. contentPatch: function(fakeStub){
  495. fakeStub.find("title").text(fakeStub.find('meta[name="keywords"]').attr("content"));
  496. }
  497. },
  498. {siteName: "逐浪",
  499. url: /^http:\/\/book\.zhulang\.com\/.*\.html/,
  500. titleReg: /(.*?)-(.*)/,
  501. contentSelector: "#readpage_leftntxt",
  502. contentHandle: false,
  503. contentPatch: function(fakeStub){
  504. var title = fakeStub.find(".readpage_leftnzgx a:first").text() + "-" +
  505. fakeStub.find(".readpage_leftntit").text();
  506. fakeStub.find('title').html(title);
  507. }
  508. },
  509. {siteName: "小说阅读网",
  510. url: "http://www\\.readnovel\\.com/novel/.*\\.html",
  511. titleSelector: ".bgtop > h1",
  512. bookTitleSelector: ".nownav > a:eq(4)",
  513. contentSelector: "#article, .zhangjie",
  514. contentRemove: "div[style], .miaoshu, .zhichi, .bottomAdbanner",
  515. contentPatch: function(fakeStub) {
  516. // 删除标题不需要的部分
  517. fakeStub.find(".bgtop > h1 > span").remove();
  518. }
  519. },
  520. // {siteName: "磨铁",
  521. // url: 'http://www.motie.com/book/\\d+_\\d+',
  522. // contentSelector: '.page-content'
  523. // },
  524.  
  525. {siteName: "百度贴吧(手动启用)",
  526. enable: false,
  527. url: /^http:\/\/tieba\.baidu.com\/p\//,
  528. titleSelector: "h1.core_title_txt",
  529. bookTitleSelector: ".card_title_fname",
  530. nextSelector: false,
  531. indexSelector: 'a.card_title_fname',
  532. prevSelector: false,
  533.  
  534. contentSelector: "#j_p_postlist",
  535. contentRemove: "#sofa_post, .d_author, .share_btn_wrapper, .core_reply, .j_user_sign",
  536. style: ".clear { border-top:1px solid #cccccc; margin-bottom: 50px; visibility: visible !important;}", // 显示楼层的分割线
  537. },
  538. // {siteName: "天涯在线书库(部分支持)",
  539. // url: /www\.tianyabook\.com\/.*\.htm/,
  540. // titleSelector: ".max, h1:first",
  541. // bookTitleSelector: "td[width='70%'] > a[href$='index.htm']",
  542. // contentSelector: "div > span.middle, #texts",
  543. // contentHandle: false,
  544. // },
  545. {siteName: "天涯书库",
  546. url: /www\.ty2016\.com\/.+\.html$/,
  547. titleSelector: "h1",
  548. bookTitleSelector: ".crumb a[href='./']",
  549.  
  550. indexSelector: "td a[href='./']",
  551.  
  552. contentSelector: "#main",
  553. contentRemove: '.crumb, table',
  554. contentHandle: false,
  555. },
  556.  
  557. // {siteName: "易读",
  558. // url: "http://www.yi-see.com/read_\\d+_\\d+.html",
  559. // contentSelector: 'table[width="900px"][align="CENTER"]'
  560. // },
  561. {siteName: "燃文",
  562. url: /^http:\/\/www\.(?:ranwen\.cc|64mi\.com)\/.*\.html$/,
  563. titleReg: /(.*?)-(.*?)-燃文/,
  564. contentSelector: "#oldtext, #contents",
  565. contentRemove: "div[style], script",
  566. contentReplace: [
  567. /\((&nbsp;)*\)/g,
  568. /最快更新78小说|\(?百度搜.\)|访问下载tXt小说|百度搜\|索|文\|学|文学全文.字手打|\((&nbsp;)+|牛过中文..hjsm..首发.转载请保留|\[本文来自\]|♠思♥路♣客レ|※五月中文网 5y ※|无错不跳字|最快阅读小说大主宰.*|跟我读H-u-n 请牢记|非常文学|关闭&lt;广告&gt;|w w.*|”娱乐秀”|更多精彩小[说說].*|高速更新/g,
  569. /[\(\*◎]*(百度搜)?文.?[學学].?[馆館][\)\*)]*|\(百度搜\)/g,
  570. /提供无弹窗全文字在线阅读.*|高速首发.*如果你觉的本章节还不错的话.*/g,
  571. /书网∷更新快∷无弹窗∷纯文字∷.t!。/g,
  572. /一秒记住,本站为您提供热门小说免费阅读。/g,
  573. /\(更新速度最快记住即可找到\)|芒果直播网|.mgzhibo .|去 读 读|看小说就到/g,
  574. ]
  575. },
  576. {siteName: "燃文小说网",
  577. url: "http://www\\.ranwenxiaoshuo\\.com/files/article/html/\\d+/\\d+/\\d+\\.html|http://www\\.ranwenxiaoshuo\\.com/\\w+/\\w+-\\d+-\\d+\\.html",
  578. titleReg: /(.*?)最新章节(.*?)在线阅读.*/,
  579. contentSelector: "#fontsize",
  580. contentReplace: "天才一秒记住[\\s\\S]+为您提供精彩小说阅读。",
  581. },
  582. {siteName: "燃文小说",
  583. url: "http://www\\.ranwen\\.net/files/article/\\d+/\\d+/\\d+\\.html",
  584. titleReg: "(\\S+) (.*) - 燃文小说",
  585. contentReplace: "\\(.*燃文小说.*\\)|【 注册会员可获私人书架,看书更方便!永久地址: 】 "
  586. },
  587. {siteName: "无错小说网",
  588. url: /^http:\/\/www\.(?:wcxiaoshuo|xiaoshuoz|quledu)\.com\/wcxs[-\d]+\//,
  589. titleReg: /(.*?)最新章节.*?-(.*?)-.*/,
  590. titlePos: 1,
  591. nextSelector: "a#htmlxiazhang",
  592. prevSelector: "a#htmlshangzhang",
  593. indexSelector: "a#htmlmulu",
  594. contentReplace: [
  595. 'ilo-full-src="\\S+\\.jpg" ',
  596. {
  597. '(<center>)?<?img src..(http://www.wcxiaoshuo.com)?(/sss/\\S+\\.jpg).(>| alt."\\d+_\\d+_\\d*\\.jpg" />)(</center>)?': '$3',
  598. "/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": "",
  599. },
  600. ".*ddefr\\.jpg.*|无(?:错|.*cuoa?w\\.jpg.*)小说网不[少跳]字|w[a-z\\.]*om?|.*由[【无*错】].*会员手打[\\s\\S]*",
  601. "无错不跳字|无广告看着就是爽!|一秒记住.*|全文免费阅读.*|8 9 阅阅 读 网|看小说最快更新|“小#说看本书无广告更新最快”",
  602. "[\\x20-\\x7e》]?无(?:.|&gt;)错.小说.{1,2}[Ww]+.*?[cC][oO][mM]",
  603. "<无-错>",
  604. "—无—错—小说",
  605. "\\+无\\+错\\+",
  606. "+无+错+小说+3W.++com",
  607. "无错小说 www.quled[Uu].com",
  608. ],
  609. contentPatch: function(fakeStub){
  610. // 去除内容开头、结尾的重复标题
  611. var title = fakeStub.find("#htmltimu").text().replace(/\s+/, "\\s*");
  612. var content = fakeStub.find("#htmlContent");
  613. content.find("div[align='center']").remove();
  614. if(title.match(/第\S+章/)){
  615. content.html(content.html().replace(new RegExp(title), "").replace(new RegExp(title), ""));
  616. }
  617. }
  618. },
  619. {siteName: '凤舞文学网',
  620. url: '^http://www\\.qiuwu\\.net/html/\\d+/\\d+/\\d+\\.html',
  621. contentReplace: [
  622. {
  623. '<img src="/keywd/R43.gif">':'爱', '<img src="/keywd/A13.gif">': '情', '<img src="/keywd/D10.gif">': '床',
  624. '<img src="/keywd/Y19.gif">': '奸', '<img src="/keywd/H21.gif">': '屁', '<img src="/keywd/Z23.gif">': '逼',
  625. '<img src="/keywd/G42.gif">': '身', '<img src="/keywd/Y2.gif">':'性', '<img src="/keywd/D32.gif">':'热',
  626. '<img src="/keywd/I44.gif">':'挺', '<img src="/keywd/H30.gif">':'贱', '<img src="/keywd/H25.gif">':'荡',
  627. '<img src="/keywd/V7.gif">':'肉', '<img src="/keywd/O22.gif">':'吮', '<img src="/keywd/H9.gif">':'春',
  628. '<img src="/keywd/K36.gif">':'日', '<img src="/keywd/O15.gif">':'胸', '<img src="/keywd/S31.gif">':'欲',
  629. '<img src="/keywd/F20.gif">':'射', '<img src="/keywd/N12.gif">':'禁', '<img src="/keywd/R26.gif">':'殿',
  630. '<img src="/keywd/N12.gif">':'禁', '<img src="/keywd/X6.gif">':'诱', '<img src="/keywd/U46.gif">': '娇',
  631. '<img src="/keywd/M24.gif">': '操', '<img src="/keywd/B4.gif">':'骚', '<img src="/keywd/O3.gif">':'阴',
  632. }
  633. ]
  634. },
  635. {siteName: "书迷楼",
  636. url: /^http:\/\/www\.shumilou\.com\/.*html$/,
  637. titleReg: /(.*) (.*?) 书迷楼/,
  638. titlePos: 1,
  639. contentSelector: "#content",
  640. contentRemove: 'a, center',
  641. contentReplace: [
  642. 'div lign="ener"&gt;|.*更多章节请到网址隆重推荐去除广告全文字小说阅读器',
  643. '起点中文网www.qidian.com欢迎广大书.*',
  644. '书迷楼最快更新.*',
  645. '更新最快最稳定',
  646. '\\(\\.\\)R?U',
  647. {'<p>\\?\\?': '<p>'},
  648. '\\(www.\\)',
  649. '章节更新最快',
  650. '-乐-读-小-说--乐读x-',
  651. '《乐》《读》小说.乐读.Com',
  652. '纯文字在线阅读本站域名手机同步阅读请访问',
  653. ],
  654. fixImage: true,
  655. contentPatch: function(fakeStub){
  656. fakeStub.find("#content").find("div.title:last")
  657. .appendTo(fakeStub.find('body'));
  658. fakeStub.find("#content").find("div.title, p > b, div[style]").remove();
  659. }
  660. },
  661. {siteName: "冰火中文",
  662. url: /^http:\/\/www\.binhuo\.com\/html\/[\d\/]+\.html$/,
  663. titleReg: /(.*?)最新章节,(.*?)-.*/,
  664. fixImage: true,
  665. contentRemove: 'font[color="red"]',
  666. contentReplace: {
  667. "&lt;冰火#中文.*|冰火中文&nbsp;(www.)?binhuo.com(?:【首发】|)|冰.火.中文|绿色小说|lvsexs|冰火中文": "",
  668. "LU5.coM|lU5.com|LU5.com":"",
  669. "([^/])www\\.binhuo\\.com(?:\\.com|)": "$1",
  670. "\\(.*?平南文学网\\)": "",
  671. },
  672. contentPatch: function(fakeStub){
  673. fakeStub.find("#BookText").append(fakeStub.find("img.imagecontent"));
  674. }
  675. },
  676. {siteName: "百晓生",
  677. url: /^http:\/\/www\.bxs\.cc\/\d+\/\d+\.html/,
  678. titleReg: /(.*?)\d*,(.*)/,
  679. contentRemove: 'a, #txtright',
  680. contentReplace: [
  681. /一秒记住【】www.zaidu.cc,本站为您提供热门小说免费阅读。/ig,
  682. /(文&nbsp;學馆w&nbsp;ww.w&nbsp;xguan.c&nbsp;om)/ig,
  683. /(百晓生更新最快最稳定\)/g,
  684. /\((?:&nbsp;)*(?:无弹窗)?全文阅读\)/ig,
  685. /\[<a.*?首发\[百晓生\] \S+/ig,
  686. /高速首发.*本章节是地址为/ig,
  687. /\/\/(?:&nbsp;|访问下载txt小说|高速更新)+\/\//ig,
  688. /(www\.)?bxs\.cc|www\.bxs(\.com)?/ig,
  689. /百晓生.不跳字|不跳字。|更新快纯文字/ig,
  690. /\.\[,!\]/ig,
  691. /(未完待续&nbsp;http:\/\/www.Bxs.cc&nbsp;89免费小说阅《百晓生文学网》)/g,
  692. /〖百晓生∷.*〗|《?百晓生文学网》?|最快阅读小说大主宰,尽在百晓生文学网.*|ww.x.om|欢迎大家来到.*?bxs\.cc|百晓生阅读最新最全的小说.*|百晓生网不少字|站长推荐.*|文字首发|百.晓.生.|关闭.*广告.*|飘天文学|本站域名就是.*|\(.{0,5}小说更快更好.{0,5}\)|(请在)?百度搜索.*|一秒记住.*为您提供精彩小说阅读.|百晓生|¤本站网址:¤|\/\/&nbsp;访问下载txt小说\/\/◎◎|纯站点\\".*值得收藏的/ig,
  693. /文[学學][馆館]|www\.biquge\.cc|(http:\/\/)?www\.Bxs\.cc|(请牢记)?soudu.org/ig,
  694. /请搜索,小说更好更新更快!|最快文字更新无弹窗无广|\(即可找到本站\)|无广告看着就是爽!|更多全本txt小说请到下载|∷更新快∷∷纯文字∷/ig,
  695. /永久网址,请牢记!/ig,
  696. /&nbsp;&gt;<\/p>/ig,
  697. ],
  698. },
  699. {siteName: "浩奇文学网",
  700. url: /^http:\/\/www\.haoqi99\.com\/.*\.shtml$/,
  701. titleReg: /^(.*?)--(.*?)-/,
  702. },
  703. {siteName: "书河小说网",
  704. url: /^http:\/\/www\.shuhe\.cc\/\d+\/\d+/,
  705. titleReg: "([^\\d]+)\\d*,(.*?)_",
  706. contentSelector: "#TXT",
  707. contentReplace: /一秒记住.*为您提供精彩小说阅读.|\{请在百度搜索.*首发阅读\}|(书河小说网.*?无弹窗)|wxs.o|ww.x.om|[\[【\(].{1,30}[\]\)】]|ff37;.*|书河小说网高速首发.*|TXT下载|全文阅读|第一书河小说网|百书斋.*|首发来自书河小说网|本书最新章节|书河小说网/ig,
  708. },
  709. {siteName: "爱收藏",
  710. url: /http:\/\/www\.aishoucang\.com\/\w+\/\d+\.html/,
  711. titleReg: "(.*?)-(.*?)-爱收藏",
  712. contentSelector: "#zhutone",
  713. contentReplace: {
  714. "<a[^>]*>(.*?)</a>": "$1",
  715. ".爱收藏[^<]*": ""
  716. }
  717. },
  718. {siteName: "木鱼哥",
  719. url: /http:\/\/(www\.)?muyuge\.(com|net)\/\w+\/\d+\.html/,
  720. titleSelector: "#yueduye h1",
  721. bookTitleSelector: ".readerNav > li > a:last",
  722. indexSelector: ".readerFooterPage a[title='(快捷:回车键)']",
  723. // useiframe: true,
  724. // mutationSelector: "#content",
  725. // mutationChildCount: 1,
  726. contentRemove: ".vote",
  727. contentReplace: {
  728. "<a[^>]*>(.*?)</a>": "$1",
  729. "看更新最快的小说就搜索—— 木鱼哥——无弹窗,全文字": "",
  730. "【看最新小说就搜索.*全文字首发】": "",
  731. "<p>.*?无弹窗</p>":"",
  732. "bb\\.king|【木&nbsp;鱼&nbsp;哥&nbsp;.*?】|【一秒钟记住本站:muyuge.com.*木鱼哥】":"",
  733. "——推荐阅读——[\\s\\S]+": "",
  734. "【\\s*木\\s*鱼\\s*哥.*?】":"",
  735. "div&gt;|&lt;-》": "",
  736. "\\(.pn. 平南\\)": "",
  737. },
  738. startFilter: function() {
  739. clearInterval(unsafeWindow.show);
  740. }
  741. },
  742. {siteName: "追书网",
  743. url: "^http://www\\.zhuishu\\.net/files/article/html/.*\\.html",
  744. titleReg: /(?:正文 )?(.*) (\S+) \S+ - .*/,
  745. titlePos: 1,
  746. indexSelector: ".pagebottom>a:contains('目录')",
  747. nextSelector: ".pagebottom>a:contains('下一页')",
  748. prevSelector: ".pagebottom>a:contains('上一页')",
  749. fixImage: true,
  750. contentSelector: "#content",
  751. contentReplace: {
  752. "([^/])www\\.ZhuisHu\\.net": "$1",
  753. },
  754. contentPatch: function(fakeStub){
  755. fakeStub.find("#content > .title, #content > .pagebottom").appendTo(fakeStub.find("body"));
  756.  
  757. fakeStub.find("#content").find("center, b:contains('最快更新')").remove();
  758. }
  759. },
  760. {siteName: "猪猪岛小说",
  761. url: "http://www\\.zhuzhudao\\.(?:com|cc)/txt/",
  762. titleReg: "(.*?)最新章节-(.*?)-",
  763. contentReplace: /[“"”]?猪猪岛小说.*|<\/?a[^>]+>|w+\.zhuZhuDao\.com|看更新最快的.*/ig
  764. },
  765. {siteName: "逸名文学屋",
  766. url: "http://(bbs\\.vyming|www\\.9imw)\\.com/novel-read-\\d+-\\d+\\.html",
  767. contentSelector: "#showcontent",
  768. bookTitleSelector: ".headinfo a:first",
  769. contentRemove: "p:contains(精品推荐:), p:contains(,免费小说阅读基地!), a",
  770. contentReplace: [
  771. "逸名文学屋:"
  772. ]
  773. },
  774. {siteName: "奇书屋",
  775. url: "http://www.qishuwu.com/\\w+/\\d+/",
  776. titleReg: "(.*)_(.*)_.*_奇书屋",
  777. },
  778. {siteName: "17k小说网",
  779. url: /^http:\/\/\S+\.17k\.com\/chapter\/\S+\/\d+\.html$/,
  780. titleReg: /(.*?)-(.*?)-.*/,
  781. contentSelector: "#chapterContent",
  782. contentRemove: "#authorSpenk, .like_box, #hotRecommend, .ct0416, .recent_read, div[style], #miniVoteBox"
  783. },
  784. {siteName: "看下文学",
  785. url: "^http://www\\.kanxia\\.net/k/\\d*/\\d+/\\d+\\.html$",
  786. titleReg: /(.*?)-(.*)TXT下载_看下文学/,
  787. contentReplace: /看下文学/g
  788. },
  789. {siteName: "青帝文学网",
  790. url: /^http:\/\/www\.qingdi\.com\/files\/article\/html\/\d+\/\d+\/\d+\.html$/,
  791. titleReg: /(.*?)最新章节_(.*?)_青帝文学网_.*/
  792. },
  793. {siteName: "侠客中文网",
  794. url: /^http:\/\/www\.xkzw\.org\/\w+\/\d+\.html/,
  795. contentSelector: ".readmain_inner .cont",
  796. contentPatch: function(fakeStub){
  797. fakeStub.find('title').html(fakeStub.find('.readmain_inner h2').text());
  798. }
  799. },
  800. {siteName: "ChinaUnix.net",
  801. url: /^http:\/\/bbs\.chinaunix\.net\/thread-.*\.html/,
  802. contentSelector: ".t_f:first"
  803. },
  804. {siteName: "123du 小说",
  805. url: /^http:\/\/www\.123du\.(?:net|cc)\//,
  806. titleReg: "(.*)-(.*) 百家乐",
  807. titlePos: 1,
  808. contentSelector: "#content, #contents",
  809. contentReplace: "一秒记住.www.*|小说最新更新,来123读书www.123du.net",
  810. contentRemove: "a",
  811. contentPatch: function(fakeStub){
  812. var content = fakeStub.find("#DivContentBG").html().match(/第\d*页([\s\S]*)一秒记住/)[1];
  813. $('<div id="content"/>').html(content).appendTo(fakeStub.find('body'));
  814. }
  815. },
  816. {siteName: "动力中文",
  817. url: "^http://dlzw\\.cc/article.*\\.html",
  818. nextSelector: "span:contains('下一篇') > a",
  819. prevSelector: "span:contains('上一篇') > a",
  820. indexSelector: "#pt a[href^='http']"
  821. },
  822. {siteName: "塔读文学",
  823. url: "^http://www\\.tadu\\.com/book/\\d+/\\d+/",
  824. bookTitleSelector: '.title em:first',
  825. contentSelector: "#partContent",
  826. contentPatch: function(fakeStub){
  827. var m = fakeStub.find("body").html().match(/\.html\(unescape\("(.*)"\)/);
  828. if(m){
  829. var unescapeContent = m[1];
  830. fakeStub.find("#partContent").html(unescape(unescapeContent));
  831. }
  832. }
  833. },
  834. {siteName: "第一中文",
  835. url: "^http://www\\.dyzww\\.com/cn/\\d+/\\d+/\\d+\\.html$" ,
  836. contentReplace: {
  837. '<img.*?ait="(.*?)".*?>': "$1",
  838. 'www\\.dyzww\\.com.*|♂|шШщ.*': ""
  839. }
  840. },
  841. {siteName: "来书屋",
  842. url: "http://www.laishuwu.com/html/\\d+/\\d+/\\d+.html",
  843. titleSelector: ".chaptertitle h2",
  844. bookTitleSelector: ".chaptertitle h1",
  845. contentReplace: "txt\\d+/",
  846. },
  847. {siteName: "万书吧",
  848. url: "http://www\\.wanshuba\\.com/Html/\\d+/\\d+/\\d+\\.html",
  849. titleReg: "(.*?),(.*?)-万书吧",
  850. titlePos: 1,
  851. contentSelector: ".yd_text2",
  852. contentReplace: [
  853. "\\[www.*?\\]",
  854. "\\(&nbsp;&nbsp;\\)",
  855. "提供无弹窗全文字在线阅读,更新速度更快文章质量更好,如果您觉得不错就多多分享本站!谢谢各位读者的支持!",
  856. "高速首发.*?,本章节是.*?地址为如果你觉的本章节还不错的话请不要忘记向您qq群和微博里的朋友推荐哦!"
  857. ]
  858. },
  859. {siteName: "大文学",
  860. url: "^http://www\\.dawenxue\\.net/html/\\d+/\\d+/\\d+\\.html",
  861. titleReg: "(.*?)-(.*)-大文学",
  862. contentSelector: "#clickeye_content",
  863. contentReplace: "\\(?大文学\\s*www\\.dawenxue\\.net\\)?|\\(\\)",
  864. },
  865. {siteName: "奇热",
  866. url: "^http://www\\.qirexs\\.com/read-\\d+-chapter-\\d+\\.html",
  867. titleReg: "(.*?)-(.*?)-",
  868. titlePos: 1,
  869. contentSelector: "div.page-content .note",
  870. contentRemove: "a",
  871. contentReplace: "”奇热小说小说“更新最快|首发,/.奇热小说网阅读网!|奇热小说网提供.*|\\(手机用户请直接访问.*"
  872. },
  873. {siteName: "热点",
  874. url: "^http://www\\.hotsk\\.com/Html/Book/\\d+/\\d+/\\d+\\.shtml",
  875. titleReg: "(.*?) 正文 (.*?)- 热点书库 -",
  876. contentReplace: "\\(热点书库首发:www.hotsk.com\\)|www.zhuZhuDao.com .猪猪岛小说."
  877. },
  878. {siteName: "落秋中文",
  879. url: "^http://www\\.luoqiu\\.(com|net)/html/\\d+/\\d+/\\d+\\.html",
  880. titleReg: "(.*?)-(.*?)-",
  881. contentReplace: "&lt;/p&gt;"
  882. },
  883. {siteName: "全本小说网",
  884. url: "^http://www\\.qb5\\.com/xiaoshuo/\\d+/\\d+/\\d+\\.html",
  885. titleReg: "(.*)_(.*)_",
  886. contentRemove: "div[class]",
  887. contentReplace: "全.{0,2}本.{0,2}小.{0,2}说.{0,2}网.{0,2}|[wWw ]+.{1,10}[CccǒOmMМ ]+",
  888. },
  889. {siteName: "手牵手小说网",
  890. url: "^http://www\\.sqsxs\\.com/.*\\d+/\\d+/\\d+\\.html",
  891. bookTitleSelector: '#sitebar a:last',
  892. contentReplace: [
  893. "◆免费◆",
  894. "★百度搜索,免费阅读万本★|访问下载txt小说.百度搜.|免费电子书下载|\\(百度搜\\)|『文學吧x吧.』|¤本站网址:¤",
  895. "[☆★◆〓『【◎◇].*?(?:yunlaige|云 来 阁|yunlaige|免费看).*?[☆◆★〓』】◎◇]",
  896. "【手机小说阅读&nbsp;m.】",
  897. "BAIDU_CLB_fillSlot.*",
  898. "&nbsp;关闭</p>",
  899. "&nbsp;&nbsp;&nbsp;&nbsp;\\?",
  900. "\\[☆更.新.最.快☆无.弹.窗☆全.免.费\\]",
  901. '\\(.*?平南文学网\\)',
  902. '{首发}|【首发】',
  903. '=长=风',
  904. { "。\\.": "。" },
  905. ]
  906. },
  907. {siteName: "六月中文网,盗梦人小说网",
  908. url: "^http://www\\.(?:6yzw\\.org|6yzw\\.com|daomengren\\.com)/.*\\.html",
  909. bookTitleSelector: ".con_top>a:last",
  910. contentRemove: "a[href]",
  911. contentReplace: [
  912. "纯文字在线阅读本站域名 520xs.Com 手机同步阅读请访问 M.520xs.Com",
  913. "{飘天文学[\\s\\S]*您的支持就是我们最大的动力}",
  914. "((未完待续),|精彩推荐:,)?最新最快更新热门小说,享受无弹窗阅读就在:",
  915. "一秒记住【】,本站为您提供热门小说免费阅读。",
  916. "百度搜索 本书名.*",
  917. "欢迎您的光临,任何搜索引擎搜索.*给大家带来的不便深感抱歉!!",
  918. "\\(?&nbsp;&nbsp; ?提供』。如果您喜欢这部作品,欢迎您来创世中文网[\\s\\S]+",
  919. "[\\((]未完待续.{1,2}本文字由.*",
  920. "//添加开头|会员特权抢先体验",
  921. "更新最快|更新快纯文字|看最新章节|六月中文网|78小说|h﹒c﹒d|穿越小说吧 sj131|\\*五月中文网5.c om\\*",
  922. "\\d楼[\\d\\-: ]+(?:&nbsp;)+ \\|(?:&nbsp;)+|吧主\\d+(?:&nbsp;)+|支持威武,嘎嘎!",
  923. "www,|&nbsp;\\\\|“梦”(&nbsp;| )*“小”(&nbsp;| )*(“说” )?“网”|“岛”(&nbsp;| )+“说”",
  924. /(百度搜索 )?本书名 \+ 盗梦人 看最快更新/ig,
  925. "520xs.com ”520小说“小说章节更新最快",
  926. "本文由 …… 首发",
  927. "看最新最全小说|最快更新,(?:无弹窗)?阅读请。",
  928. "(首发)|【首发】",
  929. "纯文字在线阅读本站域名  手机同步阅读请访问",
  930. "&amp;nbsp",
  931. ]
  932. },
  933. {siteName: "飞卢小说网",
  934. url: "^http://b\\.faloo\\.com/p/\\d+/\\d+\\.html",
  935. titleSelector: "#title h1",
  936. bookTitleSelector: "div.nav > a:last",
  937. nextSelector: "a#next_page",
  938. prevSelector: "a#pre_page",
  939. indexSelector: "a#huimulu",
  940. contentSelector: "#main > .main0",
  941. contentRemove: "> *:not(#con_imginfo, #content)",
  942. contentReplace: "飞卢小说网 b.faloo.com 欢迎广大书友光临阅读,最新、最快、最火的连载作品尽在飞卢小说网!",
  943. contentPatch: function(fakeStub){
  944. fakeStub.find("#content").find(".p_gonggao").remove();
  945. // fakeStub.find("#con_imginfo").prependTo("#content");
  946. }
  947. },
  948. {siteName: "顶点小说",
  949. url: "^http://www\\.(?:23us|23wx|xs222)\\.com/html/\\d+/\\d+/\\d+\\.html$",
  950. titleReg: "(.*?)-\\S*\\s(.*?)-顶点小说",
  951. titlePos: 0,
  952. indexSelector: "#footlink a:contains('返回目录')",
  953. prevSelector: "#footlink a:contains('上一页')",
  954. nextSelector: "#footlink a:contains('下一页')",
  955. contentSelector: "#contents",
  956. contentReplace: [
  957. "\\(看小说到顶点小说网.*\\)|\\(\\)|【记住本站只需一秒钟.*】",
  958. ],
  959. contentPatch: function(fakeStub){
  960. var temp=fakeStub.find('title').text();
  961. var realtitle = temp.replace(/第.*卷\s/,'');
  962. fakeStub.find('title').html(realtitle);
  963. }
  964. },
  965. {siteName: '23中文',
  966. url: '^http://www\\.23zw\\.com/.*\\.html',
  967. contentReplace: [
  968. '本文由首发',
  969. '章节更新最快',
  970. '顶点小说.23us.。',
  971. '\\(顶点小说\\)',
  972. '看最新最全',
  973. '看.*?最新章节到长风文学',
  974. 'R1152',
  975. ]
  976. },
  977. {siteName: '笔下阁',
  978. url: "^http://www\\.bixiage\\.com/\\w+/\\d+/\\d+/\\d+\\.html",
  979. titleReg: "(.*)最新章节免费在线阅读_(.*)_笔下阁",
  980. indexSelector: ".read_tools a:contains('返回目录')",
  981. prevSelector: ".read_tools a:contains('上一页')",
  982. nextSelector: ".read_tools a:contains('下一页')",
  983. contentReplace: [
  984. "本书最新免费章节请访问|请记住本站的网址|请使用访问本站",
  985. "看更新最快的.*www.bixiage.com",
  986. "笔下阁为您提供全文字小说.*",
  987. "如果你觉得笔下阁不错.*",
  988. "本篇是小说.*章节内容,如果你发现内容错误.*"
  989. ]
  990. },
  991. {siteName: '双德小说网',
  992. url: "^http://www\\.shuangde\\.cc/.*\\.html",
  993. bookTitleSelector: '.title > h2 > a',
  994. contentRemove: '.title, div[align="center"]',
  995. },
  996. {siteName: '爱尚小说网',
  997. url: 'http://www.a240.com/read/\\d+/\\d+.html',
  998. titleReg: '(.*) - (.*?) - 爱尚小说网',
  999. titlePos: 1,
  1000. contentRemove: '.bottem, center',
  1001. contentReplace: '<!--章节内容开始-->'
  1002. },
  1003. {siteName: 'E度文学网',
  1004. url: 'http://www.173ed.com/read/\\d+/\\d+.html',
  1005. contentRemove: 'a[href*="173e"]',
  1006. contentReplace: [
  1007. '全文字小说W.*?\\.com',
  1008. 'E度文学网更新最快',
  1009. 'www\\.♀173ed.com♀'
  1010. ]
  1011. },
  1012. {siteName: "3Z中文网",
  1013. url: "^http://www\\.zzzcn\\.com\\/(3z\\d+/\\d+\\/|modules\\/article\\/App\\.php\\?aid=\\d+&cid=\\d+){1}$",
  1014. // titleReg: "(.*?)-(.*)TXT下载",
  1015. contentSelector: "#content3zcn",
  1016. indexSelector: "a:contains('返回目录')",
  1017. prevSelector: "a:contains('上 一 页')",
  1018. nextSelector: "a:contains('下 一 页'), a:contains('返回书架')",
  1019. contentReplace: [
  1020. /[{(][a-z\/.]+(?:首发文字|更新超快)[})]/ig,
  1021. "手机小说站点(wap.zzzcn.com)",
  1022. "一秒记住.*为您提供精彩小说阅读。",
  1023. ],
  1024. contentPatch: function(fakeStub){
  1025. fakeStub.find("a:contains('返回书架')").html("下 一 页").attr("href", fakeStub.find("a:contains('返回目录')").attr("href"));
  1026. fakeStub.find("#content3zcn").find(".titlePos, font.tips, a").remove();
  1027. }
  1028. },
  1029. {siteName: "比奇中文网",
  1030. url: "http://www\\.biqi\\.me/files/article/html/\\d+/\\d+/\\d+\\.html",
  1031. titleSelector: "#lbChapterName",
  1032. bookTitleSelector: "#TOPNAV td:first > a:last",
  1033. contentReplace: [
  1034. "http://www.biqi.me比奇中文网永久网址,请牢记!",
  1035. "www.biqi.me比奇中文网一直在为提高阅读体验而努力,喜欢请与好友分享!",
  1036. "[{【]比奇中文网首发www.biqi.me[}】]",
  1037. ]
  1038. },
  1039. {siteName: "书哈哈小说网",
  1040. url: "http://(?:read|www)\\.shuhaha\\.com/Html/Book/\\d+/\\d+/\\d+\\.html",
  1041. titleSelector: "#htmltimu",
  1042. bookTitleSelector: [".srcbox > a:nth-child(2)", /目录$/],
  1043. contentSelector: "#BookText",
  1044. contentRemove: 'a[href*="www.shuhaha.com"]',
  1045. contentReplace: [
  1046. '‘‘', '’’',
  1047. '(\\.shuh&amp;n)',
  1048. /<p[^>]*>(&nbsp;){4}网<\/p>/gi
  1049. ]
  1050. },
  1051. {siteName: "SF 轻小说",
  1052. url: '^http://book.sfacg.com/Novel/\\d+/\\d+/\\d+/',
  1053. titleReg: '(.*?)-(.*?)-.*',
  1054. contentSelector: '#ChapterBody',
  1055. },
  1056. {siteName: "武林中文网",
  1057. url: '^http://www\\.50zw\\.com/book_\\d+/\\d+\\.html',
  1058. bookTitleSelector: '.srcbox > a:last',
  1059. contentReplace: [
  1060. '更新最快【】',
  1061. '&lt;/dd&gt;',
  1062. '&lt;center&gt; &lt;fon color=red&gt;'
  1063. ]
  1064. },
  1065. {siteName: "乡村小说网",
  1066. url: '^http://www\\.xiangcunxiaoshuo\\.com/shu/\\d+/\\d+\\.html',
  1067. // bookTitleSelector: '.read_m > .list',
  1068. titleReg: '(.*?)_(.*?)_.*_.*',
  1069. contentSelector: '.yd_text2',
  1070. contentReplace: [
  1071. '[wWw]+.23uS.(?:coM|com)',
  1072. '乡&amp;村&amp;.*?\\.co[mM]',
  1073. ]
  1074. },
  1075. {siteName: "杂书网",
  1076. url: "^http://www\\.zashu\\.net/books/\\d+/\\d+/\\d+\\.html",
  1077. contentReplace: [
  1078. "吋煜牝咱.*?杂书网(?:杠杠的)?",
  1079. "吋煜牝咱看书神器",
  1080. "(?:吋煜牝咱|飝现洅咱|茇阺畱匝).*?[Cc]om",
  1081. "吋煜牝咱",
  1082. "飝现洅咱", "殢萾嘎匝",
  1083. "看小说“杂书网zashu.net”",
  1084. "手机站:m.zashu.net 电脑站:www.zashu.net",
  1085. ]
  1086. },
  1087. {siteName: "小说巴士",
  1088. url: "^http://www\\.xs84\\.com/\\d+_\\d+/",
  1089. bookTitleSelector: ".con_top a:last",
  1090. contentReplace: [
  1091. "§推荐一个无广告的小说站.*? §",
  1092. "☆本站最快更新.*?☆",
  1093. "纯文字在线阅读.*?</br>",
  1094. "www.X S 8 4.com",
  1095. "《》 www.obr />",
  1096. "。。 w.2.obr",
  1097. "\\[w w w.x s.*?.c o m 小说.*?\\]",
  1098. "╂上.*?╂",
  1099. ],
  1100. contentPatch: function() {
  1101. $('<script>')
  1102. .text('clearInterval(show);')
  1103. .appendTo('body')
  1104. .remove();
  1105. }
  1106. },
  1107. {siteName: "123言情",
  1108. url: 'http://www\\.123yq\\.com/read/\\d+/\\d+/\\d+\\.shtml',
  1109. bookTitleSelector: '.con_top > a:last',
  1110. contentSelector: "#TXT",
  1111. contentRemove: '.bottem, .red',
  1112. },
  1113.  
  1114. // === 内容补丁
  1115. {siteName: "给力文学小说阅读网",
  1116. url: "^http://www\\.geiliwx\\.com/.*\\.shtml",
  1117. titleReg: "-?(.*)_(.*)最新章节_给力",
  1118. titlePos: 1,
  1119. contentRemove: 'h1, font[color], center',
  1120. contentReplace: [
  1121. "网站升级完毕!感谢对给力文学网的支持!",
  1122. "(百度搜索给力文学网更新最快最稳定\\)",
  1123. "【sogou,360,soso搜免费下载小说】",
  1124. "\\[乐\\]\\[读\\]小说.23.[Cc]m",
  1125. "给力文学网",
  1126. "看最快更新",
  1127. "小说网不跳字",
  1128. "\\.com",
  1129. "BAIDU_CLB_fillSlot\\(.*",
  1130. "--小-说-www-23wx-com",
  1131. "&nbsp;&nbsp;,请",
  1132. ],
  1133. contentPatch: function(d) {
  1134. if (!d.find('#content').length) {
  1135. var html = d.find('body').html();
  1136. var content = html.match(/<!--go-->([\s\S]*?)<!--over-->/i)[1];
  1137.  
  1138. content = $('<div id="content">').html(content);
  1139. if (content.find('#adright').size()) {
  1140. content = content.find('#adright')
  1141. }
  1142. content.appendTo(d.find('body'));
  1143. }
  1144. }
  1145. },
  1146.  
  1147. // ================== 采用 iframe 方式获取的 ====================
  1148. {siteName: "16K小说网",
  1149. url: "^http://www\\.16kbook\\.org/Html/Book/\\d+/\\d+/\\d+\\.shtml$",
  1150. titleReg: '(\\S+) (.*)- 16K小说网',
  1151. useiframe: true,
  1152. contentRemove: '.bdlikebutton',
  1153. contentReplace: {
  1154. '(<center>)?<?img src..(http://www.16kbook.org)?(/tu/\\S+\\.jpg).(>| alt."\\d+_\\d+_\\d*\\.jpg" />)(</center>)?': "$3",
  1155. "/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":"的",
  1156. "16kbook\\s*(首发更新|小说网)": "",
  1157. }
  1158. },
  1159. {siteName: "读读看",
  1160. url: "^http://www\\.dudukan\\.net/html/.*\\.html$",
  1161. contentReplace: "看小说“就爱读书”|binhuo|www\\.92to\\.com",
  1162. useiframe: true,
  1163. mutationSelector: "#main",
  1164. mutationChildCount: 0,
  1165. },
  1166. {siteName: "读零零",
  1167. url: "http://www\\.du00\\.com/read/\\d+/\\d+/[\\d_]+\\.html",
  1168. titleReg: "(.*?)(?:第\\d+段)?,(.*) - 读零零小说网",
  1169. titlePos: 1,
  1170. prevSelector: "#footlink a:first",
  1171. indexSelector: "#footlink a:contains('目录')",
  1172. nextSelector: "#footlink a:last",
  1173. // 内容
  1174. contentSelector: "#pagecontent, .divimage",
  1175. useiframe: true,
  1176. mutationSelector: "#pagecontent",
  1177. mutationChildCount: 2,
  1178. contentRemove: "font",
  1179. contentReplace: [
  1180. "读零零小说网欢迎您的光临.*?txt格式下载服务",
  1181. ",好看的小说:|本书最新免费章节请访问。",
  1182. "\\*文學馆\\*",
  1183. "\\(未完待续请搜索,小说更好更新更快!",
  1184. "www\\.DU00\\.com"
  1185. ],
  1186. checkSection: true
  1187. },
  1188. {siteName: "78小说网",
  1189. url: "^http://www\\.78xs\\.com/article/\\d+/\\d+/\\d+.shtml$",
  1190. contentHandle: false,
  1191. titleReg: "(.*?) (?:正文 )?(.*) 78小说网",
  1192. indexSelector: "a:contains('目 录')",
  1193. prevSelector: "a:contains('上一章')",
  1194. nextSelector: "a:contains('下一章')",
  1195. contentSelector: "#content",
  1196. useiframe: true,
  1197. contentReplace: [
  1198. "//.*?78xs.*?//",
  1199. "\\(全文字小说更新最快\\)",
  1200. ],
  1201. contentPatch: function(fakeStub){
  1202. fakeStub.find('p.title').empty(); // 去掉内容中带的章节标题
  1203. }
  1204. },
  1205. {siteName: "151看书网",
  1206. url: "^http://www\\.151kan\\.com/kan/.*\\.html",
  1207. contentSelector: "#msg",
  1208. useiframe: true,
  1209. mutationSelector: "#msg",
  1210. contentReplace: [
  1211. /[\/|]?www\.151(?:看|kan)\.com[\/|]?/ig,
  1212. /151看书网(?:纯文字)?/ig,
  1213. ]
  1214. },
  1215. {siteName: "就爱读书",
  1216. url: "^http://www\\.92to\\.com/\\w+/\\w+/\\d+\\.html$",
  1217. titleReg: "(.*?)-(.*?)-",
  1218. useiframe: true,
  1219. timeout: 500,
  1220. contentReplace: "看小说.就爱.*"
  1221. },
  1222. {siteName: "书书网",
  1223. url: "http://www\\.shushuw\\.cn/shu/\\d+/\\d+\\.html",
  1224. titleReg: "(.*) (.*?) 书书网",
  1225. titlePos: 1,
  1226. useiframe: true,
  1227. timeout: 500,
  1228. contentReplace: "!~![\\s\\S]*"
  1229. },
  1230. {siteName: "找小说网",
  1231. url: "http://www\\.zhaoxiaoshuo\\.com/chapter-\\d+-\\d+-\\w+/",
  1232. titleReg: "(.*) - (.*) - 找小说网",
  1233. titlePos: 1,
  1234. useiframe: true,
  1235. timeout: 500,
  1236. contentRemove: "div[style]"
  1237. },
  1238. {siteName: "ABC小说网",
  1239. url: "^http://www\\.bookabc\\.net/.*\\.html",
  1240. useiframe: true
  1241. },
  1242.  
  1243. // ============== 内容需要2次获取的 =========================
  1244. {siteName: "手打吧",
  1245. url: /^http:\/\/shouda8\.com\/\w+\/\d+\.html/,
  1246. contentReplace: /[w\s\[\/\\\(]*.shouda8.com.*|(\/\/)?[全文字]?首发|手打吧|www.shou.*|\(w\/w\/w.shouda8.c\/o\/m 手、打。吧更新超快\)|小说 阅读网 www.xiaoshuoyd .com/ig,
  1247. contentPatch: function(fakeStub){
  1248. var scriptSrc = fakeStub.find('body').html().match(/outputContent\('(.*txt)'\)/)[1];
  1249. scriptSrc = "http://shouda8.com/ajax.php?f=http://shouda8.com/read" + scriptSrc;
  1250. fakeStub.find('#content').attr({
  1251. "class": 'reader-ajax',
  1252. src: scriptSrc
  1253. });
  1254. }
  1255. },
  1256. {siteName: "哈哈文学",
  1257. url: /^http:\/\/www\.hahawx\.com\/.*htm/,
  1258. titleReg: /(.*?)-(.*?)-.*/,
  1259. contentSelector: "#chapter_content",
  1260. contentReplace: /(?:好书推荐|书友在看|其他书友正在看|好看的小说|推荐阅读):。|(?:www|www|book).*(?:com|net|org|com|net)|全文字阅读|无弹窗广告小说网|哈哈文学\(www.hahawx.com\)|souDU.org|Soudu.org|jīng彩推荐:/ig,
  1261. contentPatch: function(fakeStub){
  1262. var $content = fakeStub.find("#chapter_content");
  1263. var m = $content.find("script").text().match(/output\((\d+), "(\d+\.txt)"\);/);
  1264. if(m && m.length == 3){
  1265. var aid = m[1],
  1266. files = m[2];
  1267. var subDir = "/" + (Math.floor(aid / 1000) + 1),
  1268. subDir2 = "/" + (aid - Math.floor(aid / 1000) * 1000);
  1269. $content.attr({
  1270. class: "reader-ajax",
  1271. src: "http://r.xsjob.net/novel" + subDir + subDir2 + "/" + files,
  1272. charset: "gbk"
  1273. });
  1274. }
  1275. }
  1276. },
  1277. {siteName: "天天中文",
  1278. url: "http://www\\.ttzw\\.com/book/\\d+/\\d+\\.html",
  1279. titleSelector: "#chapter_title",
  1280. bookTitleSelector: ".fl.pl20 a:last",
  1281. contentSelector: "#text_area",
  1282. contentReplace: /www.ttzw.com|www.c66c.com|手机用户请到阅读。|<p>\s*a<\/p>/ig,
  1283. contentPatch: function(fakeStub) {
  1284. var m = fakeStub.find('#text_area script').text().match(/outputTxt\("(.*)"\);/);
  1285. if (m) {
  1286. fakeStub.find('#text_area').attr({
  1287. class: "reader-ajax",
  1288. src: unsafeWindow.getServer() + m[1],
  1289. charset: "gbk"
  1290. });
  1291. }
  1292. }
  1293. },
  1294.  
  1295. // ===========================================================
  1296. {siteName: "好看小說網",
  1297. url: "http://tw\\.xiaoshuokan\\.com/haokan/\\d+/\\d+\\.html",
  1298. contentSelector: ".bookcontent",
  1299. prevSelector: "a.redbutt:contains('上一頁')",
  1300. indexSelector: "a.redbutt:contains('返回章節目錄')",
  1301. nextSelector: "a.redbutt:contains('下一頁')",
  1302. contentReplace: "[a-z;&]*w.[xx]iaoshuokan.com 好看小說網[a-z;&族】)]*"
  1303. },
  1304. {siteName: "E品中文网",
  1305. url: "http://www\\.epzww\\.com/book/\\d+/\\d+",
  1306. titleReg: "(.*?),(.*?),",
  1307. contentSelector: "#showcontent",
  1308. },
  1309. {siteName: "飘天文学",
  1310. url: "http://www\\.piaotian\\.net/html/\\d+/\\d+/\\d+\\.html",
  1311. // titleReg: "(.*)最新章节,(.*),飘天文学",
  1312. bookTitleSelector: '#content > h1 > a',
  1313. contentSelector: "#content",
  1314. useiframe: true, // 否则 content 在 body 下面
  1315. contentRemove: "h1, table, .toplink",
  1316. contentReplace: [
  1317. /[{〖]请在百度搜索.*[}〗]|.(?:百度搜索飄天|无弹窗小说网).*\.Net.|\[飄天.*无弹窗小说网\]/ig,
  1318. '\\{飘天文学www.piaotian.net感谢各位书友的支持,您的支持就是我们最大的动力\\}',
  1319. '章节更新最快'
  1320. ],
  1321. },
  1322. {siteName: "天使小说网",
  1323. url: "http://www\\.tsxs\\.cc/files/article/html/\\d+/\\d+/\\d+\\.html",
  1324. contentSelector: "#content"
  1325. },
  1326. {siteName: "紫雨阁小说网",
  1327. url: "http://www\\.ziyuge\\.com/\\w+/\\w+/\\d+/\\d+/\\d+\\.html",
  1328. titleReg: "(.*?)-正文-(.*?)-紫雨阁小说网",
  1329. contentSelector: ".reader_content",
  1330. nextSelector: "#divNext a",
  1331. prevSelector: "#divPrev a",
  1332. contentReplace: "\\(.*www.ziyuge.com.*\\)"
  1333. },
  1334. {siteName: "破风中文网",
  1335. url: "http://www\\.pofeng\\.net/xiaoshuo/\\d+/\\d+\\.html",
  1336. useiframe: true
  1337. },
  1338. {siteName: "读客吧",
  1339. url: "http://dukeba\\.com/book/\\d+/\\d+/\\d+\\.shtml",
  1340. useiframe: true,
  1341. contentSelector: "#content > div[style]",
  1342. contentRemove: "a, div[align]:has(font)",
  1343. },
  1344. {siteName: "一起阅",
  1345. url: "http://www\\.17yue\\.com/\\w+/\\d+/\\d+\\.html",
  1346. useiframe: true,
  1347. },
  1348. {siteName: "诺秋网",
  1349. url: "http://www\\.nuoqiu\\.com/static/\\d+/\\d+\\.html",
  1350. titleReg: "(.*) (.*) 诺秋网",
  1351. titlePos: 1,
  1352. useiframe: true,
  1353. contentReplace: "┏━━━━━━━━━━━━━━━━━━━━━━━━━┓[\\s\\S]+诺秋网文字更新最快……】@!!"
  1354. },
  1355. {siteName: "言情后花园",
  1356. url: "http://www\\.yqhhy\\.cc/\\d+/\\d+/\\d+\\.html",
  1357. titleReg: "(.*)-(.*)-.*-言情后花园",
  1358. titlePos: 1,
  1359. contentSelector: "#content",
  1360. contentRemove: "a, span[style], script",
  1361. contentReplace: "请记住本站: www.yqhhy.cc|更多,尽在言情后花园。"
  1362. },
  1363. {siteName: "六九中文",
  1364. url: "http://www.(?:69zw|kan7).com/\\w+/\\d+/\\d+/\\d+.html",
  1365. titleSelector: ".chapter_title",
  1366. bookTitleSelector: ".readhead h1",
  1367. contentSelector: ".yd_text2",
  1368. // titleReg: "(.*)?_(.*)-六九中文",
  1369. contentReplace: [
  1370. "[\\*]+本章节来源六九中文.*请到六九中文阅读最新章节[\\*]+|-\\\\[wW]+.*书友上传/-",
  1371. "\\\\请到 www.69zw.com 六\\*九.*?/",
  1372. "【 注册会员可获私人书架,看书更方便!:】",
  1373. "首发<br />",
  1374. ]
  1375. },
  1376. {siteName: "免费小说阅读网",
  1377. titleReg: "(.*) , (.*) , 免费小说阅读网",
  1378. titlePos: 1,
  1379. url: "^http://book\\.yayacms\\.com/\\w+/book_\\d+_\\d+.html",
  1380. contentRemove: "a, div[style]",
  1381. contentReplace: "http://book.YaYaCMS.com/.*|book.yayacms.com",
  1382. },
  1383. {siteName: "书农在线书库",
  1384. url: "http://www\\.shunong\\.com/yuedu/\\d+/\\d+/\\d+.html",
  1385. contentSelector: ".bookcontent",
  1386. },
  1387. {siteName: "努努书坊",
  1388. url: "http://(?:book\\.kanunu\\.org|www\\.kanunu8\\.com)/.*/\\d+\\.html",
  1389. titleReg: /(.*) - (.*) - 小说在线阅读 - .* - 努努书坊/,
  1390. titlePos: 1,
  1391. contentSelector: "table:eq(4) p",
  1392. indexSelector: "a[href^='./']",
  1393. },
  1394. {siteName: "五月中文网",
  1395. url: "^http://5ycn\\.com/\\d+/\\d+/\\d+\\.html",
  1396. contentRemove: "div[align='center'], a",
  1397. },
  1398. {siteName: "笔下中文",
  1399. url: "^http://www\\.bxzw\\.org/\\w+/\\d+/\\d+/\\d+\\.shtml",
  1400. contentRemove: "div[align='center'], center, #footlink1",
  1401. contentReplace: "www\\.bxzw\\.org|//无弹窗更新快//|\\(看精品小说请上.*\\)|\\(看.*最新更新章节.*\\)"
  1402. },
  1403. {siteName: "着笔中文网",
  1404. url: "^http://.*zbzw\\.com/\\w+/\\d+\\.html",
  1405. contentReplace: "精彩小说尽在.*"
  1406. },
  1407. {siteName: "D586小说网",
  1408. url: 'http://www\\.d586\\.com/',
  1409. contentSelector: ".yd_text2",
  1410. contentRemove: 'a',
  1411. contentReplace: [
  1412. '【www.13800100.com文字首发D586小说网】',
  1413. '【☆D586小说网☆//文字首发】.*'
  1414. ]
  1415. },
  1416. {siteName: "豌豆文学网",
  1417. url: "^http://www.wandoou.com/book/\\d+/\\d+\\.html",
  1418. titleReg: '(.*?)最新章节-(.*)-.*无弹窗广告_豌豆文学网',
  1419. contentRemove: "center",
  1420. contentReplace: [
  1421. /[{(]<a href.*[})]|网欢迎广大书友光临阅读,.*/ig,
  1422. /[レ★]+.*(?:请支持)?豌(?:.|&amp;)?豆.?文.?学.*[レ★]+/ig,
  1423. /[((【]豌.?豆.?文.?学.*[))】]/ig,
  1424. /∷更新快∷∷纯文字∷|http:永久网址,请牢记!/ig,
  1425. /(?:{|\\|\/|\()*豌.?豆.?文.?学.?网.*?(?:高速更新|\\\/|})+/ig,
  1426. /更新最快最稳定|看小说“”/ig,
  1427. /&lt;strng&gt;.*?&lt;\/strng&gt;/ig,
  1428. /\(凤舞文学网\)|\( *\)|「启航文字」|79阅.读.网/ig,
  1429. /高速首发.*?本章节是.*/ig,
  1430. /百度搜索自从知道用百度搜索,妈妈再也不用担心我追不到最快更新了/ig,
  1431. ]
  1432. },
  1433. {siteName: "都来读小说网",
  1434. url: /^http:\/\/www\.doulaidu\.com\/[^\/]+\/\d+\/\d+\.html/,
  1435. useiframe: true,
  1436. contentReplace: [
  1437. /www..+.(?:com|net)/ig,
  1438. /都来读小说网首发|www\.[a-z0-9]+\.(?:org|com)/ig,
  1439. ]
  1440. },
  1441. {siteName: "小说TXT",
  1442. url: /^http:\/\/www\.xshuotxt\.com\//,
  1443. contentReplace: "\\(.*无弹窗全文阅读\\)",
  1444. contentPatch: function(fakeStub) {
  1445. fakeStub.find('#title a').remove();
  1446. }
  1447. },
  1448. {siteName: "疯狂中文网",
  1449. url: "http://www\\.fkzww\\.com/",
  1450. contentRemove: ".bottem, a[href='http://www.fkzww.com']",
  1451. contentReplace: [
  1452. /收藏【.*?疯狂中文网\)/ig,
  1453. ]
  1454. },
  1455. {siteName: "吾读小说网",
  1456. url: "http://www\\.5du5\\.com/book/.*\\.html",
  1457. contentReplace: '\\(吾读小说网 <a.*无弹窗全文阅读\\)'
  1458. },
  1459. {siteName: "UU看书",
  1460. url: "http://www\\.uukanshu\\.com/.*/\\d+/\\d+.html",
  1461. contentReplace: "[UU]*看书[(\\(].*?[)\\)]文字首发。"
  1462. },
  1463. {siteName: "长风文学网",
  1464. url: "http://www\\.cfwx\\.net/files/article/html/\\d+/\\d+/\\d+\\.html",
  1465. titleSelector: '.title',
  1466. bookTitleSelector: '.linkleft > a:last',
  1467. contentReplace: [
  1468. '[《(\\+[]长.{1,2}风.{1,2}文学 www.*?net',
  1469. ]
  1470. },
  1471. {siteName: "云来阁",
  1472. url: "http://www\\.yunlaige\\.com/html/\\d+/\\d+/\\d+\\.html",
  1473. titleSelector: '.ctitle',
  1474. bookTitleSelector: '#hlBookName',
  1475. contentSelector: '#content',
  1476. contentRemove: '.bottomlink, a',
  1477. contentReplace: [
  1478. '[☆★◆〓『【◎◇].*?(?:yunlaige|云 来 阁|yunlaige).*?[☆◆★〓』】◎◇]',
  1479. '《更新最快小说网站:雲来阁http://WWW.YunLaiGe.COM》',
  1480. '◢百度搜索雲来阁,最新最快的小说更新◣',
  1481. '【最新更新】',
  1482. '值得您收藏。。',
  1483. '小说“小说章节',
  1484. '纯文字在线阅读本站域名',
  1485. '手机同步阅读请访问',
  1486. '\\(云来阁小说文学网www.yunlaige.com\\)',
  1487. '【本书作者推荐:(?:百度搜索)?云来閣,免费观看本书最快的VIP章节】',
  1488. ]
  1489. },
  1490. {siteName: "乐文小说网",
  1491. url: /http:\/\/www\.lwxs520\.com\/books\/\d+\/\d+\/\d+.html/,
  1492. siteExample: 'http://www.lwxs520.com/books/2/2329/473426.html',
  1493. contentRemove: '#content>:not(p)',
  1494. contentReplace: [
  1495. '喜欢乐文小说网就上www.*(?:COM|com)',
  1496. '爱玩爱看就来乐文小说网.*',
  1497. '\\(LWXS520。\\)',
  1498. 'M.LWxS520.com&nbsp;乐文移动网',
  1499. /\(未完待续.+/g,
  1500. /乐文小说网值得.+/g,
  1501. '\\(\\)',
  1502. ]
  1503. },
  1504. {siteName: '我爱小说',
  1505. url: '^http://www\\.woaixiaoshuo\\.com/xiaoshuo/\\d+/\\d+/\\d+\\.html',
  1506. bookTitleSelector: '#lbox > b',
  1507. contentSelector: '#readbox',
  1508. contentRemove: '#papgbutton, #content',
  1509. },
  1510. {siteName: "米花在线书库",
  1511. url: /book\.mihua\.net\/\w+\/\d+\/\d+\/.+\.html/,
  1512. titleSelector: "#title",
  1513. contentSelector: "#viewbook"
  1514. },
  1515. {siteName: "58小说网",
  1516. url: /^http:\/\/(www|book)\.(58)?58xs\.com\/html\/\d+\/\d+\/\d+\.html/,
  1517. titleSelector: "h1",
  1518. indexSelector: "#footlink > a:eq(1)",
  1519. prevSelector: "#footlink > a:eq(0)",
  1520. nextSelector: "#footlink > a:eq(2)",
  1521. contentSelector: "#content",
  1522. contentRemove: ".f1, .c1"
  1523. },
  1524. {siteName: "天天美文网",
  1525. url: /www\.365essay\.com\/\w+\/.+.htm/,
  1526. titleSelector: ".title > h1",
  1527. contentSelector: "#zoomc td",
  1528. contentRemove: ".page-bottomc"
  1529. },
  1530. {siteName: "天涯武库",
  1531. url: /wx\.ty2016\.com\/.+\.html$/,
  1532. bookTitleSelector: "td[width='800'][height='25']>a[href='./']",
  1533. titleSelector: "strong>font",
  1534. indexSelector: "td a[href='./']",
  1535. nextSelector: "td[width='28%'] a",
  1536.  
  1537. contentSelector: "td[width='760'] p",
  1538. contentHandle: false,
  1539. },
  1540. {siteName: "黄金屋中文网",
  1541. url: /www\.hjwzw\.com\/Book\/Read\/\d+,\d+$/,
  1542. titleSelector: "h1",
  1543. indexSelector: "td a[href='./']",
  1544. contentSelector: "#AllySite+div",
  1545. contentRemove: "b, b+p"
  1546. },
  1547. {siteName: "梦远书城",
  1548. url: /www\.my285\.com(?:\/\w+){3,5}\/\d+\.htm$/,
  1549. useiframe: true,
  1550. contentSelector: "table:eq(2) tr:eq(3)",
  1551. },
  1552. {siteName: "更新吧",
  1553. url: "^http://www\\.gengxin8\\.com/read/\\d+/\\d+.html$",
  1554. bookTitleSelector: '.left a:last',
  1555. contentSelector: "#chaptertxt",
  1556. useiframe: true,
  1557. },
  1558. {siteName: "乐文小说网",
  1559. url: "http://www\\.365xs\\.org/books/\\d+/\\d+/\\d+\\.html",
  1560. titleSelector: ".kfyd h1",
  1561. bookTitleSelector: "ul.bread-crumbs a:last",
  1562. contentSelector: "#content",
  1563. // contentReplace: []
  1564. },
  1565.  
  1566. // ===== 特殊的获取下一页链接
  1567. {siteName: "看书啦",
  1568. url: "^http://www.kanshu.la/book/\\w+/\\d+\\.shtml",
  1569. titleReg: "(.*)-(.*)-看书啦",
  1570. titlePos: 1,
  1571. nextUrl: function($doc){
  1572. var html = $doc.find('script:contains(next_page = ")').html();
  1573. var m = html.match(/next_page = "(.*?)";/);
  1574. if (m) return m[1];
  1575. },
  1576. prevUrl: function($doc){
  1577. var html = $doc.find('script:contains(preview_page = ")').html();
  1578. var m = html.match(/preview_page = "(.*?)";/);
  1579. if (m) return m[1];
  1580. }
  1581. },
  1582. {siteName: "书阁网",
  1583. url: "^http://www\\.bookgew\\.com/Html/Book/\\d+/\\d+/\\d+\\.htm",
  1584. titleReg: "(.*)-(.*?)-书阁网",
  1585. titlePos: 1,
  1586. // titleSelector: ".newstitle",
  1587. nextUrl: function($doc){
  1588. var html = $doc.find('script:contains(nextpage=)').html();
  1589. var m = html.match(/nextpage="(.*?)";/);
  1590. if (m) return m[1];
  1591. },
  1592. prevUrl: function($doc) {
  1593. var html = $doc.find('script:contains(prevpage=)').html();
  1594. var m = html.match(/prevpage="(.*?)";/);
  1595. if (m) return m[1];
  1596. }
  1597. },
  1598.  
  1599. // {siteName: "雅文言情小说吧", // 一章分段
  1600. // url: "http://www\\.yawen8\\.com/\\w+/\\d+/\\d+\\.html",
  1601. // contentSelector: "#content .txtc"
  1602. // }
  1603.  
  1604. {siteName:'妙笔阁',
  1605. url:/^http:\/\/www\.miaobige\.com\/.*\.html/i,
  1606. siteExample:'http://www.miaobige.com/book/5_1586/1006320.html',
  1607. // 有的会提示防采集章节
  1608. fInit: function () {
  1609. $('<script>')
  1610. .text('$(document).unbind("contextmenu selectstart")')
  1611. .appendTo(document.body);
  1612. },
  1613. contentReplace: '妙笔阁,无弹窗,更新快,记住www.miaobige.com',
  1614. contentPatch: function(fakeStub){
  1615. var txt = fakeStub.find('#content'),
  1616. mNewLink;
  1617.  
  1618. if (0 === txt.text().trim().indexOf('防采集章节,')) {
  1619. mNewLink = txt.html().match(/http:\/\/www\.miaobige\.com\/book\/(\d)_(\d+)\/(\d+)\.html/i);
  1620. if (mNewLink) {
  1621. txt .addClass(READER_AJAX)
  1622. .attr({
  1623. src: '/js/ajaxtxt.asp',
  1624. charset: 'gbk'
  1625. })
  1626. .data('post', {
  1627. sid: mNewLink[2],
  1628. zid: mNewLink[3],
  1629. cid: mNewLink[1]
  1630. })
  1631. .text('请等待加载…');
  1632. }
  1633. }
  1634. }
  1635. },
  1636.  
  1637. ];
  1638.  
  1639. // ===== 全局移除 =====
  1640. Rule.replaceAll = [
  1641. /[;\(]顶.{0,2}点.小说/ig,
  1642. /www.23+?[Ww][Xx].[Cc]om/ig,
  1643. /乐文移动网/g,
  1644. /》长>风》/g,
  1645. /热门推荐:、+/g,
  1646. /h2&gt;/g,
  1647. ];
  1648.  
  1649. // ===== 小说拼音字、屏蔽字修复 =====
  1650. Rule.replace = {
  1651. // ===格式整理===
  1652. // "\\(|\\[|\\{|(|【|{":"(",
  1653. // "\\)|\\]|\\}|)|】|}":")",
  1654.  
  1655. // 需要?
  1656. ",": ",",
  1657. // ":": ":", "\\?":"?", // 会造成起点的图片无法替换
  1658.  
  1659. "\\*|*":"*",
  1660. "[wWwW]{3}":"www",
  1661. "w{3}(\u3001|\u3002)":"www.",
  1662. "[cCcC][oOoO][mMmM]":"com",
  1663. "[nNnN][eeEE][ttTT]":"net",
  1664. "[cCcC][nNnN]":"cn",
  1665. "(\\.|\u3001|\u3002)com":".com",
  1666. "(\\.|\u3001|\u3002)net":".net",
  1667. "(\\.|\u3001|\u3002)cn":".cn",
  1668. "[pPpP][sSsS][::]":"ps:",
  1669. "。{5,7}":"……","~{2,50}":"——","…{3,40}": "……","-{3,20}":"——",
  1670. //"。(,|,|。)": "。",
  1671. // "?(,|,)": "?",
  1672. //"”(,|,|。)": "”",
  1673. "@{3,}": "",
  1674.  
  1675. // === 一些特殊的替换 ===
  1676. "\\[+CP.*(http://file.*\\.jpg)\\]+": "<img src='$1'>",
  1677. "『(.)』": "$1", // "『色』": "色",
  1678.  
  1679. // === 去广告 ===
  1680. "\\[搜索最新更新尽在[a-z\\.]+\\]": "",
  1681. "<a>手机用户请到m.qidian.com阅读。</a>": "",
  1682. ".{2,4}中文网欢迎广大书友": "",
  1683. "访问下载txt小说|◎雲來閣免费万本m.yunlaige.com◎":"",
  1684. "〖∷更新快∷无弹窗∷纯文字∷.*?〗": "",
  1685. "本文由 。。 首发":"",
  1686. '”小说“小说章节更新最快': '',
  1687. '如果觉得好看,请把本站网址推荐给您的朋友吧!': '',
  1688. '本站手机网址:&nbsp;&nbsp;请互相通知向您QQ群【微博/微信】论坛贴吧推荐宣传介绍!': '',
  1689. "fqXSw\\.com":"", "\\.5du|\\.5du5\\.":"",
  1690. "\\[\\]":"",
  1691. "如果您觉得网不错就多多分享本站谢谢各位读者的支持": "",
  1692. "全文字无广告|\\(看书窝&nbsp;看书窝&nbsp;无弹窗全文阅读\\)": "",
  1693. "。。+[\\s ]*看最新最全小说": "",
  1694. "水印广告测试": "",
  1695. "\\(平南文学网\\)":"", "讀蕶蕶尐說網":"",
  1696. "比奇提示:如何快速搜自己要找的书籍":"", "《百度书名\\+比奇》即可快速直达":"",
  1697. "[:《〈|~]长.风.文~?学.*?net": "",
  1698. "~无~错~小~说": "",
  1699.  
  1700. "\\(一秒记住小说界\\)|\\*一秒记住\\*":"",
  1701. "uutxt\\.org|3vbook\\.cn|www\\.qbwx\\.com|WWw\\.YaNkuai\\.com|www\\.btzw\\.com|www\\.23uS\\.com": "",
  1702. "txt53712/": "",
  1703. "\xa0{4,12}":"\xa0\xa0\xa0\xa0\xa0\xa0\xa0",
  1704.  
  1705. // === 通用去广告
  1706. "[wwW]{1,3}[.\\.]23uS[.\\.](?:coM|com)": "",
  1707.  
  1708. // === 星号屏蔽字还原 ===
  1709. "十有(\\*{2})":"十有八九","十有bā'九":"十有八九", "\\*{2}不离十":"八九不离十",
  1710. "G(\\*{2})":"GSM", "感(\\*{2})彩":"感情色彩",
  1711. "强(\\*{2})u5B9D":"强大法宝",
  1712.  
  1713. // === 多字替换 ===
  1714. "cao之过急":"操之过急", "chunguang大泄":"春光大泄",
  1715. "大公无si":"大公无私",
  1716. "fu道人家":"妇道人家", "放sōng'xià来":"放松下来",
  1717. "奸yin掳掠":"奸淫掳掠",
  1718. "空dangdang":"空荡荡",
  1719. "突发qing况": "突发情况",
  1720. "yin奉阳违":"阴奉阳违", "一yin一阳":"一阴一阳",
  1721.  
  1722. // === 双字替换 ===
  1723. "暧m[eè][iì]":"暧昧",
  1724. "bàn\\s*fǎ":"办法", "bucuo":"不错", "不liáng":"不良", "b[ěe]i(\\s|&nbsp;)*j[īi]ng":"北京","半shen": "半身", "b[ìi]j[ìi]ng":"毕竟", "报(了?)jing":"报$1警", "bèi'pò":"被迫", "包yǎng":"包养", "(?:biǎo|婊\\\\?)子":"婊子", "biǎo\\s*xiàn\\s*":"表现",
  1725. "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 luo"":"赤裸",
  1726. "dān\\s*xīn":"当心", "dang校": "党校", "da子": "鞑子", "大tui":"大腿", "dǎ\\s*suàn":"打算", "dengdai":"等待", "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国":"帝国", "du[oò]落":"堕落", "坠luò":"坠落",
  1727. "f[ǎa]ngf[óo]":"仿佛", "fei踢": "飞踢", "feng流": "风流", "风liu": "风流", "f[èe]nn[ùu]":"愤怒", "fǎn\\s*yīng":"反应",
  1728. "gao潮": "高潮", "高氵朝":"高潮", "gāo\\s*xìng\\s*":"高兴", "干chai": "干柴", "勾yin":"勾引", "gu[oò]ch[ée]ng":"过程", "gu[āa]n\\s*x[iì]":"关系", "g[ǎa]nji[àa]o":"感觉", "国wu院":"国务院", "gù\\s*yì\\s*":"故意", "guofen":"过分",
  1729. "hā\\s*hā\\s*":"哈哈", "h[aǎ]ode":"好的", "hù士":"护士", "火qiang":"火枪", "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*":"合适",
  1730. "jian(臣|细)":"奸$1", "奸yin":"奸淫", "jiànmiàn":"见面", "jian货":"贱货", "jing察":"警察", "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色":"角色",
  1731. "k[ěe]n[ée]ng": "可能", "开bao": "开苞", "k[àa]o近": "靠近", "口wen":"口吻", "kankan":"看看",
  1732. "ling辱": "凌辱", "luan蛋": "卵蛋", "脸sè": "脸色", "lu出":"露出", "流máng":"流氓", "lun理":"伦理", "lì\\s*qì":"力气",
  1733. "m[ǎa]ny[ìi]":"满意", "m[ǎa]sh[àa]ng":"马上", "m[ée]iy[oǒ]u":"没有", "mei国": "美国", "m[íi]ngb[áa]i":"明白", "迷huan": "迷幻", "mi茫":"迷茫", "mó\\s*yàng":"模样", "m[íi]n\\s{0,2}zh[ǔu]": "民主", "迷jian": "迷奸", "mimi糊糊":"迷迷糊糊", "末(?:\\s|<br/?>)*ì":"末日", "面se":"面色", "mengmeng":"蒙蒙",
  1734. "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":"内裤",
  1735. "pi[áa]o客":"嫖客", "p[áa]ngbi[āa]n":"旁边",
  1736. "q[íi]gu[àa]i":"奇怪", "qing\\s*(ren|人)":"情人", "qin兽":"禽兽", "q[iī]ngch[uǔ]":"清楚", "què\\s*dìng":"确定", "球mi":"球迷", "青chun":"青春", "青lou":"青楼", "qingkuang":"情况", "qiang[ \\s]*jian":"强奸",
  1737. "re\\s*nao":"热闹", "r[úu]gu[oǒ]":"如果", "r[oó]ngy[ìi]":"容易", "ru(房|白色)": "乳$1", "rén员":"人员", "rén形":"人形", "人chao":"人潮", "renmen":"人名",
  1738. "she(门|术|手|程|击)":"射$1", "sudu":"速度", "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": "上床", "呻y[íi]n": "呻吟", "sh[ēe]ngzh[íi]": "生殖", "深gu": "深谷", "双xiu": "双修", "生r[ìi]": "生日", "si盐":"私盐", "shi卫":"侍卫", "si下":"私下", "sao扰":"骚扰", "shuang feng":"双峰",
  1739. "t[uū]r[áa]n":"突然", "tiaojiao": "调教", "偷qing":"偷情", "推dao": "推倒", "脱guang": "脱光", "t[èe]bi[ée]":"特别", "t[ōo]nggu[òo]":"通过", "同ju":"同居", "tian来tian去":"舔来舔去",
  1740. "w[ēe]ixi[ée]":"威胁", "wèizh[ìi]":"位置", "wei员":"委员", "w[èe]nti":"问题", "wèi\\s*dào\\s*":"味道", "wú\\s*nài":"无奈", "weilai":"未来",
  1741. "xiu长": "修长", "亵du": "亵渎", "xing福": "幸福", "小bo":"小波", "小niū":"小妞", "xiong([^a-z])":"胸$1", "小tui":"小腿", "xiàohuà":"笑话", "xiàn\\'zhì":"限制", "xiōng\\s*dì":"兄弟",
  1742. "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è情":"一夜情",
  1743. "z[iì]j[iǐ]": "自己","z[ìi](?:\\s|<br/?>|&nbsp;)*y[oó]u": "自由","zh[iī]d?[àa]u?o":"知道", "zixin":"自信", "zhì'fú":"制服", "zha药": "炸药", "zhan有": "占有", "zhè\\s*gè":"这个", "政f[ǔu]": "政府", "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":"周围", "中nan海":"中南海", "中j委":"中纪委", "中zu部":"中组部", "政zhi局":"政治局", "(昨|一|时|余)(?:<br/?>|&nbsp;|\\s)*ì":"$1日", "照she":"照射", "zhǔn\\s*bèi\\s*":"准备",
  1744.  
  1745. "</p>\\n<p>\\s*ì":"日",
  1746. };
  1747.  
  1748. // 单字替换,可能会误替换,所以需要特殊处理
  1749. (function(){
  1750. var oneWordReplace = {
  1751. "b[āà]ng":"棒","bào":"爆","bà":"吧","bī":"逼","bō":"波",
  1752. "cāo": "操", "cǎo": "草", "cào": "操", "chāng": "娼", "chang": "娼", "cháo": "潮", "chā": "插", "chéng": "成", "chōu": "抽", "chuáng": "床", "chún": "唇", "chūn": "春", "cuō": "搓", "cū": "粗",
  1753. "dǎng": "党", "dàng": "荡", "dāo": "刀", "dòng": "洞", "diao": "屌",
  1754. "fǎ": "法", "féi": "肥", "fù": "妇",
  1755. "guān": "官",
  1756. "hán": "含", "hóu": "喉", "hòu": "厚", "h(u)?ā": "花", "huá": "华", "huò": "惑", "hùn": "混", "hún": "魂",
  1757. "jiǔ": "九", "jīng": "精", "jìn": "禁", "jǐng": "警", "jiāng": "江", "jiān": "奸", "jiāo": "交", "jūn": "军", "jū": "拘", "jú": "局", "jī": "激", "激ān":"奸",
  1758. "kù": "裤", "kàn": "看",
  1759. "[1l]àng": "浪", "liáo": "撩", "liú":"流", "lì":"莉", "liè":"烈", "[1l]uàn":"乱", "lún":"伦", "luǒ":"裸", "lòu":"露", "[l1]ù":"露", "lǜ":"绿",
  1760. "mǎi": "买", "mài": "卖", "máo": "毛", "mā": "妈", "méng": "蒙", "mén": "门", "miè": "灭", "mí": "迷", "mì": "蜜", "mō": "摸",
  1761. "nǎi": "奶", "nèn": "嫩", "niào": "尿", "niē": "捏", "nòng": "弄", "nǚ": "女",
  1762. "pào": "炮", "piàn": "片",
  1763. "qi[āa]ng": "枪", "qíng": "情", "qīn": "亲", "qiú": "求", "quán": "全",
  1764. "rén":"人", "rì": "日", "rǔ": "乳",
  1765. "sāo":"骚", "sǎo": "骚", "sè": "色", "shā": "杀", "shēn":"呻", "shén":"神", "shè": "射", "shǐ": "屎", "shì": "侍", "sǐ": "死", "sī": "私", "shǔn": "吮", "sǔn": "吮", "sū": "酥",
  1766. "tān":"贪", "tiǎn": "舔", "tǐng":"挺", "tǐ": "体", "tǒng": "捅", "tōu": "偷", "tou": "偷", "tuǐ": "腿", "tūn": "吞", "tún": "臀", "tiáo":"调", "tài":"态",
  1767. "wēn": "温", "wěn": "吻",
  1768. "xiǎo":"小", "xìng": "性", "xiōng": "胸", "xī": "吸", "xí": "习", "xué": "穴", "xuè": "穴", "xùe": "穴", "xuan":"宣",
  1769. "yāng":"央", "yàn":"艳", "yīn":"阴", "yào": "药", "yé": "爷", "yòu": "诱", "zàng": "脏", "yù": "欲", "yín": "淫",
  1770. "zhēn":"针", "zēn":"针", "zhà":"炸", "zhèng":"政", "zǒu": "走", "zuì":"罪", "zuò":"做", "zhōng":"中",
  1771.  
  1772. "ri":"日", "se":"色", "yu":"欲", "xing":"性",
  1773. "jing":"精", "ting":"挺",
  1774. };
  1775.  
  1776. var replaceOthers = {
  1777. // ===误替换还原===
  1778. "碧欲": "碧玉", "美欲": "美玉","欲石": "玉石","惜欲": "惜玉","宝欲": "宝玉",
  1779. "品性": "品行", "德性": "德行",
  1780. "波ok": "book", "波SS": "BOSS",
  1781.  
  1782. // ===其他修正===
  1783. "弥俩": "你俩",
  1784. "妳": "你",
  1785. "圞|垩|卝|龘":""
  1786. };
  1787.  
  1788. _.each(oneWordReplace, function(value, key) {
  1789. Rule.replace['([^a-z\\s])' + key + '(?![a-z\\s])'] = '$1' + value;
  1790. });
  1791.  
  1792. _.extend(Rule.replace, replaceOthers);
  1793. })();
  1794.  
  1795.  
  1796. // 自定义的
  1797. Rule.customRules = [];
  1798. Rule.customReplace = {};
  1799.  
  1800. Rule.parseCustomReplaceRules = function(str) {
  1801. var arr = str.split(/\n/);
  1802. var rules = {};
  1803. _.each(arr, function(b) {
  1804. var pos = b.indexOf('=');
  1805. if (pos === -1) return;
  1806.  
  1807. var key = b.substring(0, pos),
  1808. value = b.substring(pos + 1, b.length);
  1809. rules[key] = value;
  1810. });
  1811. return rules;
  1812. };
  1813.  
  1814.  
  1815. var getBooleanConfig = function(configName, defaultValue) {
  1816. var config = GM_getValue(configName);
  1817. if(config === undefined) {
  1818. GM_setValue(configName, defaultValue);
  1819. config = defaultValue;
  1820. }
  1821. return config;
  1822. };
  1823.  
  1824. var Config = {
  1825. getDisableAutoLaunch: function() { // 强制手动启用模式
  1826. return getBooleanConfig("disable_auto_launch", false);
  1827. },
  1828. setDisableAutoLaunch: function(bool) {
  1829. GM_setValue("disable_auto_launch", bool);
  1830. },
  1831.  
  1832. // 按键调用会遇到问题: Greasemonkey 访问违规:unsafeWindow 无法调用 GM_getValue
  1833. // 故改成这种形式
  1834. copyCurTitle: getBooleanConfig("copyCurTitle", true),
  1835. setCopyCurTitle: function (bool) {
  1836. this.copyCurTitle = !!bool;
  1837. GM_setValue("copyCurTitle", !!bool);
  1838. },
  1839.  
  1840. get cn2tw() {
  1841. if (_.isUndefined(this._cn2tw)) {
  1842. this._cn2tw = getBooleanConfig('cn2tw', Config.lang === 'zh-TW' ? true : false);
  1843. }
  1844. return this._cn2tw;
  1845. },
  1846. set cn2tw(bool) {
  1847. GM_setValue('cn2tw', bool);
  1848. this._cn2tw = bool;
  1849. },
  1850.  
  1851. get booklink_enable() { // booklink.me 跳转的自动启动
  1852. return getBooleanConfig("booklink_enable", true);
  1853. },
  1854. set booklink_enable(bool) {
  1855. GM_setValue("booklink_enable", bool);
  1856. },
  1857.  
  1858. get debug() { // 调试
  1859. if (_.isUndefined(this._debug)) {
  1860. this._debug = getBooleanConfig("debug", false);
  1861. }
  1862. return this._debug;
  1863. },
  1864. set debug(bool) {
  1865. this._debug = bool;
  1866. GM_setValue("debug", bool);
  1867. toggleConsole(bool);
  1868. },
  1869.  
  1870. get addToHistory() {
  1871. if (_.isUndefined(this._addToHistory)) {
  1872. this._addToHistory = getBooleanConfig("add_nextpage_to_history", true);
  1873. }
  1874. return this._addToHistory;
  1875. },
  1876. set addToHistory(bool) {
  1877. this._addToHistory = bool;
  1878. GM_setValue("add_nextpage_to_history", bool);
  1879. },
  1880.  
  1881. get dblclickPause() {
  1882. return getBooleanConfig('dblclick_pause', true);
  1883. },
  1884. set dblclickPause(bool) {
  1885. GM_setValue('dblclick_pause', bool);
  1886. },
  1887.  
  1888. get remain_height() { // 距离底部多少高度(px)开始加载下一页
  1889. if(_.isUndefined(this._remain_height)){
  1890. this._remain_height = parseInt(GM_getValue("remain_height"), 10) || 400;
  1891. }
  1892. return this._remain_height;
  1893. },
  1894. set remain_height(val) {
  1895. this._remain_height = val;
  1896. GM_setValue("remain_height", val);
  1897. },
  1898.  
  1899. get lang() {
  1900. if (_.isUndefined(this._lang)) {
  1901. this._lang = GM_getValue("lang") || ((navigator.language === "zh-TW" || navigator.language === "zh-HK") ? "zh-TW" : "zh-CN");
  1902. }
  1903. return this._lang;
  1904. },
  1905. set lang(val) {
  1906. this._lang = val;
  1907. GM_setValue("lang", val);
  1908. },
  1909.  
  1910. get font_family() {
  1911. return GM_getValue("font_family") || "微软雅黑,宋体,黑体,楷体".uiTrans();
  1912. },
  1913. set font_family(val) {
  1914. GM_setValue("font_family", val);
  1915. },
  1916.  
  1917. get font_size() { // 字体大小
  1918. return GM_getValue("font_size") || "18px";
  1919. },
  1920. set font_size(val) {
  1921. GM_setValue("font_size", val);
  1922. },
  1923.  
  1924. get text_line_height(){
  1925. return GM_getValue("text_line_height") || "2.25em";
  1926. },
  1927. set text_line_height(val){
  1928. GM_setValue("text_line_height", val);
  1929. },
  1930.  
  1931. get content_width() { // 内容宽度
  1932. return GM_getValue("content_width") || "800px";
  1933. },
  1934. set content_width(val) {
  1935. GM_setValue("content_width", val);
  1936. },
  1937.  
  1938. get extra_css() {
  1939. return GM_getValue("extra_css", "");
  1940. },
  1941. set extra_css(val) {
  1942. GM_setValue("extra_css", val);
  1943. },
  1944.  
  1945. get customSiteinfo() {
  1946. return GM_getValue('custom_siteinfo', '[]');
  1947. },
  1948. set customSiteinfo(val) {
  1949. GM_setValue('custom_siteinfo', val);
  1950. },
  1951.  
  1952. get customReplaceRules() {
  1953. var rules = GM_getValue('custom_replace_rules', 'b[āà]ng=棒\n『(.)』=$1');
  1954.  
  1955. return rules;
  1956. },
  1957. set customReplaceRules(val) {
  1958. GM_setValue('custom_replace_rules', val);
  1959. },
  1960.  
  1961. get skin_name() {
  1962. return GM_getValue("skin_name") || "缺省皮肤".uiTrans();
  1963. },
  1964. set skin_name(val) {
  1965. GM_setValue("skin_name", val);
  1966. },
  1967.  
  1968. get menu_list_hiddden() {
  1969. return getBooleanConfig("menu_list_hiddden", false);
  1970. },
  1971. set menu_list_hiddden(bool) {
  1972. GM_setValue("menu_list_hiddden", bool);
  1973. },
  1974.  
  1975. get hide_footer_nav() {
  1976. return getBooleanConfig("hide_footer_nav", true);
  1977. },
  1978. set hide_footer_nav(bool) {
  1979. GM_setValue("hide_footer_nav", bool);
  1980. UI.hideFooterNavStyle(bool);
  1981. },
  1982.  
  1983. get hide_preferences_button() {
  1984. return getBooleanConfig("hide_preferences_button", false);
  1985. },
  1986. set hide_preferences_button(bool) {
  1987. GM_setValue('hide_preferences_button', bool);
  1988. },
  1989.  
  1990. // === 快捷键
  1991.  
  1992. // 安静模式切换快捷键
  1993. get quietModeKey() {
  1994. if (this._quietModeKey) {
  1995. return this._quietModeKey;
  1996. }
  1997. this._quietModeKey = GM_getValue('quietModeKey') || 'q';
  1998.  
  1999. return this._quietModeKey;
  2000. },
  2001. set quietModeKey(keyCode) {
  2002. this._quietModeKey = keyCode;
  2003. GM_setValue('quietModeKey', keyCode);
  2004. },
  2005.  
  2006. // 打开设置窗口的快捷键
  2007. get openPreferencesKey() {
  2008. if (this._openPreferencesKey) {
  2009. return this._openPreferencesKey;
  2010. }
  2011. this._openPreferencesKey = GM_getValue('open_preferences_key') || 's';
  2012.  
  2013. return this._openPreferencesKey;
  2014. },
  2015. set openPreferencesKey(keyCode) {
  2016. this._openPreferencesKey = keyCode;
  2017. GM_setValue('open_preferences_key', keyCode);
  2018. },
  2019.  
  2020. // 隐藏左侧章节列表的快捷键
  2021. get hideMenuListKey() { // 默认为 c
  2022. // 'C'.charCodeAt(0) = 67
  2023. if (this._hideMenuListKey) {
  2024. return this._hideMenuListKey;
  2025. }
  2026. this._hideMenuListKey = GM_getValue('hide_menulist_key') || 'c';
  2027.  
  2028. return this._hideMenuListKey;
  2029. },
  2030. set hideMenuListKey(key) {
  2031. this._hideMenuListKey = key;
  2032. GM_setValue("hide_menulist_key", key);
  2033. },
  2034.  
  2035. get picNightModeCheck() {
  2036. return getBooleanConfig('picNightModeCheck', true);
  2037. },
  2038. set picNightModeCheck(bool) {
  2039. GM_setValue('picNightModeCheck', bool);
  2040. },
  2041.  
  2042. get split_content() {
  2043. if (_.isUndefined(this._split_content)) {
  2044. this._split_content = GM_getValue('split_content', true);
  2045. }
  2046. return this._split_content;
  2047. },
  2048. set split_content(bool) {
  2049. this._split_content = bool;
  2050. GM_setValue('split_content', bool);
  2051. },
  2052.  
  2053. get scrollAnimate() {
  2054. return GM_getValue('scrollAnimate', false);
  2055. },
  2056. set scrollAnimate(bool) {
  2057. GM_setValue('scrollAnimate', bool);
  2058. },
  2059. };
  2060.  
  2061.  
  2062. var uiTrans = {
  2063. "将小说网页文本转换为繁体。\n\n注意:内置的繁简转换表,只收录了简单的单字转换,启用本功能后,如有错误转换的情形,请利用脚本的自订字词取代规则来修正。\n例如:「千里之外」,会错误转换成「千里之外」,你可以加入规则「千里之外=千里之外」来自行修正。": "將小說網頁文字轉換為繁體。\n\n注意:內建的繁簡轉換表,只收錄了簡單的單字轉換,啟用本功能後,如有錯誤轉換的情形,請利用腳本的自訂字詞取代規則來修正。\n例如:「千里之外」,會錯誤轉換成「千裡之外」,你可以加入規則「千裡之外=千里之外」來自行修正。",
  2064. "图片章节用夜间模式没法看,这个选项在启动时会自动切换到缺省皮肤": "圖片章節無法以夜間模式觀看,這個選項在啟動時會自動切換到預設佈景",
  2065. "通过快捷键切换或在 Greasemonkey 用户脚本命令处打开设置窗口": "通過熱鍵切換或在 Greasemonkey 使用者腳本命令處開啟設定視窗",
  2066. "隐藏后通过快捷键或 Greasemonkey 用户脚本命令处调用": "隱藏後通過熱鍵或 Greasemonkey 使用者腳本命令處調用",
  2067. "一行一个,每行第一个 = 为分隔符\n需要刷新页面生效": "一行一條規則,每一行第一個 = 為分隔符\n(需重新載入頁面才能生效)",
  2068. "错误:没有找到下一页的内容,使用右键翻到下一页": "錯誤:沒有找到下一頁的內容,使用右鍵翻到下一頁",
  2069. "左键滚动,中键打开链接(无阅读模式)": "左鍵捲動畫面至該章節,中鍵開啟連結(無閱讀模式)",
  2070. "请输入切换左侧章节列表的快捷键:": "請輸入切換左側章節列表的熱鍵:",
  2071. "详见脚本代码的 Rule.specialSite": "詳見腳本代碼的 Rule.specialSite",
  2072. "booklink.me 点击的网站强制启用": "booklink.me 點擊的網站強制啟用",
  2073. "部分选项需要刷新页面才能生效": "部份選項需重新載入頁面才能生效",
  2074. "取消本次设定,所有选项还原": "取消本次設定,所有選項還原",
  2075. "不影响 booklink.me 的启用": "不影響 booklink.me 的啟用",
  2076. "请输入打开设置的快捷键:": "請輸入開啟設定視窗的熱鍵:",
  2077. "微软雅黑,宋体,黑体,楷体": "Microsoft YaHei,新細明體,PMingLiU,MingLiU,細明體,標楷體",
  2078. "夜间模式的图片章节检测": "夜間模式的圖片章節檢測",
  2079. "点击显示隐藏章节列表": "點此以顯示或隱藏章節列表",
  2080. "添加下一页到历史记录": "加入下一頁到歷史記錄",
  2081. "booklink 自动启用": "booklink 自動啟用",
  2082. "Enter 键打开目录": "Enter 鍵開啟目錄",
  2083. "隐藏左侧章节列表": "隱藏左側章節列表",
  2084. "小说阅读脚本设置":"小說閱讀腳本設定",
  2085. "已到达最后一页": "已到達最後一頁",
  2086. "正在载入下一页": "正在載入下一頁",
  2087. "通过快捷键切换": "通過熱鍵切換",
  2088. "隐藏底部导航栏": "隱藏底部導航列",
  2089. "隐藏左侧导航条": "隱藏左側章節列表彈出鈕",
  2090. "主页链接没有找到": "未找到主頁連結",
  2091. "自定义站点规则": "自訂網站規則",
  2092. "自定义替换规则": "自訂字詞取代規則",
  2093. "网页:转繁体": "網頁:轉繁體",
  2094. "双击暂停翻页": "雙擊暫停翻頁",
  2095. "隐藏设置按钮": "隱藏設定按鈕",
  2096. "强制手动启用": "強制手動啟用",
  2097. "调用阅读器": "調用閱讀器",
  2098. "自定义样式": "自訂樣式",
  2099. "界面语言": "介面語言",
  2100. "打开目录": "開啟本書目錄頁",
  2101. "自动翻页": "自動翻頁",
  2102. "缺省皮肤": "預設佈景",
  2103. "暗色皮肤": "暗色佈景",
  2104. "夜间模式": "夜間模式",
  2105. "夜间模式1": "夜間模式1",
  2106. "夜间模式2": "夜間模式2",
  2107. "橙色背景": "橙色背景",
  2108. "绿色背景": "綠色背景",
  2109. "绿色背景2": "綠色背景2",
  2110. "蓝色背景": "藍色背景",
  2111. "棕黄背景": "棕黃背景",
  2112. "经典皮肤": "經典背景",
  2113. "阅读模式": "閱讀模式",
  2114. "调试模式": "偵錯模式",
  2115. "反馈地址": "反饋與討論",
  2116. "安静模式": "安靜模式",
  2117. "√ 确认": "√ 確定",
  2118. "X 取消": "X 取消",
  2119. "上一页": "上一頁",
  2120. "下一页": "下一頁",
  2121. "状态": "狀態",
  2122. "已经": "已經",
  2123. "暂停": "暫停",
  2124. "启用": "啟用",
  2125. "退出": "離開",
  2126. "测试": "測試",
  2127. "距离": "距離",
  2128. "加载": "載入",
  2129. "字体": "字型",
  2130. "行高": "行距",
  2131. "行宽": "版面寬度",
  2132. "目录": "目錄"
  2133. };
  2134.  
  2135. if(!String.prototype.uiTrans){
  2136. Object.defineProperty(String.prototype, 'uiTrans', {
  2137. value: function(){
  2138. var _this = this.valueOf(), key, regexp;
  2139. if(Config.lang !== 'zh-TW') return _this;
  2140. if(uiTrans.hasOwnProperty(_this)) return uiTrans[_this];
  2141. for (key in uiTrans) {
  2142. regexp = new RegExp(key, 'g');
  2143. _this = _this.replace(regexp, uiTrans[key]);
  2144. }
  2145. return _this;
  2146. },
  2147. enumerable: false
  2148. });
  2149. }
  2150.  
  2151. //------------------- 辅助函数 ----------------------------------------
  2152.  
  2153. var nullFn = function() {};
  2154.  
  2155. // Check if is GM 2.x
  2156. if (typeof exportFunction == 'undefined') {
  2157. // For GM 1.x backward compatibility, should work.
  2158. var exportFunction = (function(foo, scope, defAs) {
  2159. scope[defAs.defineAs] = foo;
  2160. }).bind(unsafeWindow);
  2161. }
  2162.  
  2163. var C;
  2164. toggleConsole(Config.debug);
  2165.  
  2166. function toggleConsole(debug) {
  2167. if (debug) {
  2168. C = console;
  2169. } else {
  2170. C = {
  2171. log: nullFn,
  2172. debug: nullFn,
  2173. error: nullFn,
  2174. group: nullFn,
  2175. groupCollapsed: nullFn,
  2176. groupEnd: nullFn,
  2177. time: nullFn,
  2178. timeEnd: nullFn,
  2179. };
  2180. }
  2181. }
  2182.  
  2183. function L_getValue(key) { // 个别用户禁用本地存储会报错
  2184. try {
  2185. return localStorage.getItem(key);
  2186. } catch (e) {}
  2187. }
  2188.  
  2189. function L_setValue(key, value) {
  2190. try {
  2191. localStorage.setItem(key, value);
  2192. } catch (e) {}
  2193. }
  2194.  
  2195. function L_removeValue(key) {
  2196. try {
  2197. localStorage.removeItem(key);
  2198. } catch (e) {}
  2199. }
  2200.  
  2201.  
  2202. function parseHTML(str) {
  2203. var doc;
  2204. try {
  2205. // firefox and chrome 30+,Opera 12 会报错
  2206. doc = new DOMParser().parseFromString(str, "text/html");
  2207. } catch (ex) {}
  2208.  
  2209. if (!doc) {
  2210. doc = document.implementation.createHTMLDocument("");
  2211. doc.querySelector("html").innerHTML = str;
  2212. }
  2213. return doc;
  2214. }
  2215.  
  2216. function toRE(obj, flag) {
  2217. if (obj instanceof RegExp) {
  2218. return obj;
  2219. } else {
  2220. return new RegExp(obj, (flag || 'ig'));
  2221. }
  2222. }
  2223.  
  2224. function toReStr(str) { // 处理字符串,否则可能会无法用正则替换
  2225. return str.replace(/[()\[\]{}|+.,^$?\\*]/g, "\\$&");
  2226. }
  2227.  
  2228. function wildcardToRegExpStr(urlstr) {
  2229. if (urlstr.source) return urlstr.source;
  2230. var reg = urlstr.replace(/[()\[\]{}|+.,^$?\\]/g, "\\$&").replace(/\*+/g, function(str){
  2231. return str === "*" ? ".*" : "[^/]*";
  2232. });
  2233. return "^" + reg + "$";
  2234. }
  2235.  
  2236. function getUrlHost(url) {
  2237. var a = document.createElement('a');
  2238. a.href = url;
  2239. return a.host;
  2240. }
  2241.  
  2242. $.nano = function(template, data) {
  2243. return template.replace(/\{([\w\.]*)\}/g, function(str, key) {
  2244. var keys = key.split("."),
  2245. v = data[keys.shift()];
  2246. for (var i = 0, l = keys.length; i < l; i++) v = v[keys[i]];
  2247. return (typeof v !== "undefined" && v !== null) ? v : "";
  2248. });
  2249. };
  2250.  
  2251. // jQuery text 完全匹配. e.g. a:econtains('最新章节')
  2252. $.expr[":"].econtains = function(obj, index, meta, stack) {
  2253. return (obj.textContent || obj.innerText || $(obj).text() || "").toLowerCase() == meta[3].toLowerCase();
  2254. };
  2255.  
  2256. /* jshint ignore: start */
  2257.  
  2258. function $x(aXPath, aContext) {
  2259. var nodes = [];
  2260. var doc = document;
  2261. aContext = aContext || doc;
  2262.  
  2263. try {
  2264. var results = doc.evaluate(aXPath, aContext, null,
  2265. XPathResult.ANY_TYPE, null);
  2266. var node;
  2267. while (node = results.iterateNext()) {
  2268. nodes.push(node);
  2269. }
  2270. } catch (ex) {}
  2271.  
  2272. return nodes;
  2273. }
  2274.  
  2275. Function.prototype.getMStr = function() { // 多行String
  2276. var lines = new String(this);
  2277. lines = lines.substring(lines.indexOf("/*") + 3, lines.lastIndexOf("*/"));
  2278. return lines;
  2279. };
  2280.  
  2281. if (typeof String.prototype.startsWith != 'function') {
  2282. String.prototype.startsWith = function(str) {
  2283. return this.slice(0, str.length) == str;
  2284. };
  2285. }
  2286.  
  2287. if (typeof String.prototype.contains != 'function') {
  2288. String.prototype.contains = function(str) {
  2289. return this.indexOf(str) != -1;
  2290. };
  2291. }
  2292.  
  2293. function saveAs(data, filename) {
  2294. if(!filename) filename = 'console.json'
  2295.  
  2296. if (typeof data == 'object') {
  2297. data = JSON.stringify(data, undefined, 4);
  2298. }
  2299.  
  2300. var blob = new Blob([data], { type: 'application/octet-stream' });
  2301. var url = window.URL.createObjectURL(blob);
  2302. var saveas = document.createElement('a');
  2303. saveas.href = url;
  2304. saveas.style.display = 'none';
  2305. document.body.appendChild(saveas);
  2306. saveas.download = filename;
  2307. saveas.click();
  2308. setTimeout(function() {
  2309. saveas.parentNode.removeChild(saveas);
  2310. }, 1000)
  2311. document.addEventListener('unload', function() {
  2312. window.URL.revokeObjectURL(url);
  2313. });
  2314. }
  2315.  
  2316. /*
  2317. * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
  2318. */
  2319. 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}});
  2320.  
  2321. /* jshint ignore: end */
  2322.  
  2323.  
  2324. var UI = {
  2325. tpl_footer_nav: '\
  2326. <div class="chapter-footer-nav">\
  2327. <a class="prev-page" href="{prevUrl}">上一页</a> | \
  2328. <a class="index-page" href="{indexUrl}" title="Enter 键打开目录">目录</a> | \
  2329. <a class="next-page" style="color:{theEndColor}" href="{nextUrl}">下一页</a>\
  2330. </div>\
  2331. '.uiTrans(),
  2332. skins: {},
  2333.  
  2334. init: function(){
  2335. UI.refreshMainStyle();
  2336.  
  2337. UI.refreshSkinStyle(Config.skin_name, true);
  2338.  
  2339. UI.refreshExtraStyle(Config.extra_css);
  2340.  
  2341. UI.fixMobile();
  2342.  
  2343. // 初始变量
  2344. UI.$menu = $('#menu');
  2345. UI.$menuBar = $('#menu-bar');
  2346. UI.$content = $('#mynovelreader-content');
  2347. UI.$preferencesBtn = $('#preferencesBtn');
  2348.  
  2349. // 初始化是否隐藏
  2350. if(Config.hide_footer_nav){
  2351. UI.hideFooterNavStyle(true);
  2352. }
  2353.  
  2354. // UI.toggleQuietMode(); // 初始化安静模式
  2355. UI.hideMenuList(Config.menu_list_hiddden); // 初始化章节列表是否隐藏
  2356. UI.hidePreferencesButton(Config.hide_preferences_button); // 初始化设置按钮是否隐藏
  2357. },
  2358. refreshMainStyle: function(){
  2359. if(UI.mainStyle){
  2360. $(UI.mainStyle).remove();
  2361. }
  2362.  
  2363. UI.mainStyle = GM_addStyle(
  2364. Res.CSS_MAIN
  2365. .replace("{font_family}", Config.font_family)
  2366. .replace("{font_size}", Config.font_size)
  2367. .replace("{title_font_size}", UI.calcTitleFontSize(Config.font_size))
  2368. .replace("{content_width}", Config.content_width)
  2369. .replace("{text_line_height}", Config.text_line_height)
  2370. .replace("{menu-bar-hidden}", Config.menu_bar_hidden ? "display:none;" : "")
  2371. );
  2372. },
  2373. hideFooterNavStyle: function(hidden){
  2374. var navStyle = $("#footer_nav_css");
  2375. if(hidden) {
  2376. if(navStyle.length === 0) {
  2377. $('<style>')
  2378. .attr("id", "footer_nav_css")
  2379. .text(".chapter-footer-nav { display: none; }")
  2380. .appendTo('head');
  2381. }
  2382. } else {
  2383. navStyle.remove();
  2384. }
  2385. },
  2386. hideMenuList: function(hidden){
  2387. if(typeof(hidden) === "undefined"){
  2388. hidden = !UI.menu_list_hiddden;
  2389. }
  2390.  
  2391. if(hidden){
  2392. UI.$menu.addClass('hidden');
  2393. UI.$content.css("margin-left", "");
  2394. }else{
  2395. UI.$menu.removeClass('hidden');
  2396. UI.$content.css("margin-left", "320px");
  2397. }
  2398. UI.menu_list_hiddden = hidden;
  2399. },
  2400. hidePreferencesButton: function(hidden) {
  2401. hidden = _.isUndefined(hidden) ? Config.hide_preferences_button : hidden;
  2402.  
  2403. UI.$preferencesBtn.toggle(!hidden);
  2404. },
  2405. hideMenuBar: function(hidden) {
  2406. hidden = _.isUndefined(hidden) ? Config.menu_bar_hidden : hidden;
  2407.  
  2408. UI.$menuBar.toggle(!hidden);
  2409. },
  2410. refreshSkinStyle: function(skin_name, isFirst){
  2411. var style = $("#skin_style");
  2412. if(style.length === 0){
  2413. style = $('<style id="skin_style">').appendTo('head');
  2414. }
  2415.  
  2416. // 图片章节夜间模式会变的无法看
  2417. if (isFirst && skin_name.indexOf('夜间'.uiTrans()) != -1 && Config.picNightModeCheck) {
  2418. setTimeout(function(){
  2419. var img = $('#mynovelreader-content img')[0];
  2420. // console.log(img.width, img.height)
  2421. if (img && img.width > 500 && img.height > 1000) {
  2422. style.text(UI.skins['缺省皮肤'.uiTrans()]);
  2423. return;
  2424. }
  2425. }, 200);
  2426. }
  2427.  
  2428. style.text(UI.skins[skin_name]);
  2429. },
  2430. refreshExtraStyle: function(css){
  2431. var style = $("#extra_style");
  2432. if(style.length === 0){
  2433. style = $('<style id="extra_style">').appendTo('head');
  2434. }
  2435.  
  2436. style.text(css);
  2437. },
  2438. toggleQuietMode: function() {
  2439. this._isQuietMode = !this._isQuietMode;
  2440. var selector = '#menu-bar, #menu, #preferencesBtn, .readerbtn';
  2441.  
  2442. if (this.$_quietStyle) {
  2443. this.$_quietStyle.remove();
  2444. this.$_quietStyle = null;
  2445. }
  2446.  
  2447. if (this._isQuietMode) {
  2448. $(selector).addClass("quiet-mode");
  2449.  
  2450. if (!isChrome) { // firefox 下隐藏滚动条
  2451. this.$_quietStyle = $('<style>')
  2452. .text('scrollbar {visibility:collapse !important; } body {overflow: hidden !important; overflow-x: hidden !important;}')
  2453. .appendTo('head');
  2454. }
  2455. } else {
  2456. $(selector).removeClass("quiet-mode");
  2457. }
  2458. },
  2459. addButton: function(){
  2460. GM_addStyle('\
  2461. .readerbtn {\
  2462. position: fixed;\
  2463. right: 10px;\
  2464. bottom: 10px;\
  2465. z-index: 2247483648;\
  2466. padding: 20px 5px;\
  2467. width: 50px;\
  2468. height: 20px;\
  2469. line-height: 20px;\
  2470. text-align: center;\
  2471. border: 1px solid;\
  2472. border-color: #888;\
  2473. border-radius: 50%;\
  2474. background: rgba(0,0,0,.5);\
  2475. color: #FFF;\
  2476. font: 12px/1.5 "微软雅黑","宋体",Arial;\
  2477. cursor: pointer;\
  2478. }\
  2479. ');
  2480.  
  2481. $("<div>")
  2482. .addClass("readerbtn")
  2483. .html(App.isEnabled ? "退出".uiTrans() : "阅读模式".uiTrans())
  2484. .mousedown(function(event){
  2485. if(event.which == 1){
  2486. App.toggle();
  2487. }else if(event.which == 2){
  2488. event.preventDefault();
  2489. L_setValue("mynoverlreader_disable_once", true);
  2490.  
  2491. var url = App.activeUrl || App.curPageUrl;
  2492. App.openUrl(url);
  2493. }
  2494. })
  2495. .appendTo('body');
  2496. },
  2497. calcTitleFontSize: function(contentFontSizeStr){
  2498. var m = contentFontSizeStr.match(/([\d\.]+)(px|em|pt)/);
  2499. if(m) {
  2500. var size = m[1],
  2501. type = m[2];
  2502. return parseInt(size, 10) * 1.88 + type;
  2503. }
  2504.  
  2505. return "";
  2506. },
  2507. fixMobile: function(){ // 自适应网页设计
  2508. var meta = document.createElement("meta");
  2509. meta.setAttribute("name", "viewport");
  2510. meta.setAttribute("content", "width=device-width, initial-scale=1");
  2511. document.head.appendChild(meta);
  2512. },
  2513. preferencesShow: function(event){
  2514. if($("#reader_preferences").length){
  2515. return;
  2516. }
  2517.  
  2518. UI._loadBlocker();
  2519.  
  2520. UI.$prefs = $('<div id="reader_preferences">')
  2521. .css('cssText', 'position:fixed; top:12%; left:30%; width:500px; z-index:300000;')
  2522. .append(
  2523. $('<style>').text(Res.preferencesCSS))
  2524. .append(
  2525. $('<div class="body">').html(Res.preferencesHTML))
  2526. .appendTo('body');
  2527.  
  2528. UI.preferencesLoadHandler();
  2529. },
  2530. _loadBlocker: function() {
  2531. UI.$blocker = $('<div>').attr({
  2532. id: 'uil_blocker',
  2533. style: 'position:fixed;top:0px;left:0px;right:0px;bottom:0px;background-color:#000;opacity:0.5;z-index:100000;'
  2534. }).appendTo('body');
  2535. },
  2536. hide: function(){
  2537. if(UI.$prefs) UI.$prefs.remove();
  2538. if(UI.$blocker) UI.$blocker.remove();
  2539. UI.$prefs = null;
  2540. UI.$blocker = null;
  2541. },
  2542. preferencesLoadHandler: function(){
  2543. var $form = $("#preferences");
  2544.  
  2545. // checkbox
  2546. $form.find("#enable-cn2tw").get(0).checked = Config.cn2tw;
  2547. $form.find("#disable-auto-launch").get(0).checked = Config.getDisableAutoLaunch();
  2548. $form.find("#booklink-enable").get(0).checked = Config.booklink_enable;
  2549. $form.find("#debug").get(0).checked = Config.debug;
  2550. $form.find("#quietMode").get(0).checked = Config.isQuietMode;
  2551. $form.find("#pic-nightmode-check").get(0).checked = Config.picNightModeCheck;
  2552. $form.find("#copyCurTitle").get(0).checked = Config.copyCurTitle;
  2553.  
  2554. $form.find("#hide-menu-list").get(0).checked = Config.menu_list_hiddden;
  2555. $form.find("#hide-footer-nav").get(0).checked = Config.hide_footer_nav;
  2556. $form.find("#hide-preferences-button").get(0).checked = Config.hide_preferences_button;
  2557. $form.find("#add-nextpage-to-history").get(0).checked = Config.addToHistory;
  2558. $form.find("#enable-dblclick-pause").get(0).checked = Config.dblclickPause;
  2559.  
  2560. $form.find("#font-family").get(0).value = Config.font_family;
  2561. $form.find("#font-size").get(0).value = Config.font_size;
  2562. $form.find("#content_width").get(0).value = Config.content_width;
  2563. $form.find("#text_line_height").get(0).value = Config.text_line_height;
  2564. $form.find("#split_content").get(0).checked = Config.split_content;
  2565. $form.find("#scroll_animate").get(0).checked = Config.scrollAnimate;
  2566.  
  2567. $form.find("#remain-height").get(0).value = Config.remain_height;
  2568. $form.find("#extra_css").get(0).value = Config.extra_css;
  2569. $form.find("#custom_siteinfo").get(0).value = Config.customSiteinfo;
  2570. UI._rules = $form.find("#custom_replace_rules").get(0).value = Config.customReplaceRules;
  2571.  
  2572. // 界面语言
  2573. var $lang = $form.find("#lang");
  2574. $("<option>").text("zh-CN").appendTo($lang);
  2575. $("<option>").text("zh-TW").appendTo($lang);
  2576. $lang.val(Config.lang).change(function(){
  2577. var key = $(this).find("option:selected").text();
  2578. Config.lang = key;
  2579. });
  2580.  
  2581. // 皮肤
  2582. var $skin = $form.find("#skin");
  2583. for(var key in UI.skins){
  2584. $("<option>").text(key).appendTo($skin);
  2585. }
  2586. $skin.val(Config.skin_name).change(function(){
  2587. var key = $(this).find("option:selected").text();
  2588. UI.refreshSkinStyle(key);
  2589. Config.skin_name = key;
  2590. });
  2591.  
  2592. // 字体大小等预览
  2593. var preview = _.debounce(function(){
  2594. switch(this.id){
  2595. case "font-size":
  2596. var titleFontSize = UI.calcTitleFontSize(this.value);
  2597. if(titleFontSize) {
  2598. UI.$content.css("font-size", this.value);
  2599. UI.$content.find("h1").css("font-size", titleFontSize);
  2600. }
  2601. break;
  2602. case "font-family":
  2603. UI.$content.css("font-family", this.value);
  2604. break;
  2605. case "content_width":
  2606. UI.$content.css("width", this.value);
  2607. break;
  2608. case "text_line_height":
  2609. UI.$content.css("line-height", this.value);
  2610. break;
  2611. default:
  2612. break;
  2613. }
  2614. }, 300);
  2615. $form.on("input", "input", preview);
  2616.  
  2617. // 初始化设置按键
  2618. $form.find("#quietModeKey").get(0).value = Config.quietModeKey;
  2619. $form.find("#openPreferencesKey").get(0).value = Config.openPreferencesKey;
  2620. $form.find("#setHideMenuListKey").get(0).value = Config.hideMenuListKey;
  2621.  
  2622. // 点击事件
  2623. $form.on('click', 'input:checkbox, input:button', function(event){
  2624. UI.preferencesClickHandler(event.target);
  2625. });
  2626. },
  2627. preferencesClickHandler: function(target){
  2628. var key;
  2629. switch (target.id) {
  2630. case 'close_button':
  2631. UI.preferencesCloseHandler();
  2632. break;
  2633. case 'save_button':
  2634. UI.preferencesSaveHandler();
  2635. break;
  2636. case 'debug':
  2637. Config.debug = !Config.debug;
  2638. toggleConsole(Config.debug);
  2639. break;
  2640. case 'quietMode':
  2641. UI.toggleQuietMode(target.checked);
  2642. break;
  2643. case 'hide-menu-list':
  2644. UI.hideMenuList(target.checked);
  2645. break;
  2646. case 'hide-preferences-button':
  2647. UI.hidePreferencesButton(target.checked);
  2648. if (target.checked) {
  2649. alert('隐藏后通过快捷键或 Greasemonkey 用户脚本命令处调用'.uiTrans());
  2650. }
  2651. break;
  2652. case 'hide-footer-nav':
  2653. break;
  2654. case 'quietModeKey':
  2655. key = prompt('请输入打开设置的快捷键:'.uiTrans(), Config.quietModeKey);
  2656. if (key) {
  2657. Config.quietModeKey = key;
  2658. $(target).val(key);
  2659. }
  2660. break;
  2661. case 'openPreferencesKey':
  2662. key = prompt('请输入打开设置的快捷键:'.uiTrans(), Config.openPreferencesKey);
  2663. if (key) {
  2664. Config.openPreferencesKey = key;
  2665. $(target).val(key);
  2666. }
  2667. break;
  2668. case 'setHideMenuListKey':
  2669. key = prompt('请输入切换左侧章节列表的快捷键:'.uiTrans(), Config.hideMenuListKey);
  2670. if (key) {
  2671. Config.hideMenuListKey = key;
  2672. $(target).val(key);
  2673. }
  2674. break;
  2675. case 'saveAsTxt':
  2676. App.saveAsTxt();
  2677. break;
  2678. default:
  2679. break;
  2680. }
  2681. },
  2682. preferencesCloseHandler: function(){
  2683. // UI.$content.removeAttr("style");
  2684. UI.$content.find("h1").css("font-size", "");
  2685.  
  2686. UI.hide();
  2687. },
  2688. preferencesSaveHandler: function(){
  2689. var $form = $("#preferences");
  2690.  
  2691. Config.setDisableAutoLaunch($form.find("#disable-auto-launch").get(0).checked);
  2692.  
  2693. Config.cn2tw = $form.find("#enable-cn2tw").get(0).checked;
  2694. Config.booklink_enable = $form.find("#booklink-enable").get(0).checked;
  2695. Config.isQuietMode = $form.find("#quietMode").get(0).checked;
  2696. Config.debug = $form.find("#debug").get(0).checked;
  2697. Config.picNightModeCheck = $form.find("#pic-nightmode-check").get(0).checked;
  2698. Config.setCopyCurTitle($form.find("#copyCurTitle").get(0).checked);
  2699.  
  2700. Config.addToHistory = $form.find("#add-nextpage-to-history").get(0).checked;
  2701. Config.dblclickPause = $form.find("#enable-dblclick-pause").get(0).checked;
  2702.  
  2703. var skinName = $form.find("#skin").find("option:selected").text();
  2704. Config.skin_name = skinName;
  2705. UI.refreshSkinStyle(skinName);
  2706.  
  2707. Config.font_family = $form.find("#font-family").get(0).value;
  2708. UI.$content.css("font-family", Config.font_family);
  2709.  
  2710. Config.font_size = $form.find("#font-size").get(0).value;
  2711. Config.text_line_height = $form.find("#text_line_height").get(0).value;
  2712. Config.content_width = $form.find("#content_width").get(0).value;
  2713. Config.remain_height = $form.find("#remain-height").get(0).value;
  2714. Config.split_content = $form.find("#split_content").get(0).checked;
  2715. Config.scrollAnimate = $form.find("#scroll_animate").get(0).checked;
  2716.  
  2717. Config.menu_list_hiddden = $form.find("#hide-menu-list").get(0).checked;
  2718. UI.hideMenuList(Config.menu_list_hiddden);
  2719.  
  2720. Config.hide_footer_nav = $form.find("#hide-footer-nav").get(0).checked;
  2721. Config.hide_preferences_button = $form.find("#hide-preferences-button").get(0).checked;
  2722.  
  2723. var css = $form.find("#extra_css").get(0).value;
  2724. UI.refreshExtraStyle(css);
  2725. Config.extra_css = css;
  2726.  
  2727. Config.customSiteinfo = $form.find("#custom_siteinfo").get(0).value;
  2728.  
  2729. // 自定义替换规则直接生效
  2730. var rules = $form.find("#custom_replace_rules").get(0).value;
  2731. Config.customReplaceRules = rules;
  2732. if (rules != UI._rules) {
  2733. var contentHtml = App.oArticles.join('\n');
  2734. if (rules) {
  2735. // 转换规则
  2736. rules = Rule.parseCustomReplaceRules(rules);
  2737. // 替换
  2738. contentHtml = Parser.prototype.replaceHtml(contentHtml, rules);
  2739. }
  2740.  
  2741. UI.$content.html(contentHtml);
  2742.  
  2743. App.resetCache();
  2744.  
  2745. UI._rules = rules;
  2746. }
  2747.  
  2748. UI.hide();
  2749. },
  2750. openHelp: function() {
  2751.  
  2752. },
  2753. notice: function (htmlText){
  2754. var $noticeDiv = $("#alert");
  2755.  
  2756. clearTimeout(UI.noticeDivto);
  2757. $noticeDiv.find("p").html(htmlText);
  2758. $noticeDiv.fadeIn("fast");
  2759.  
  2760. UI.noticeDivto = setTimeout(function(){
  2761. $noticeDiv.fadeOut(500);
  2762. }, 1666);
  2763.  
  2764. return $noticeDiv;
  2765. }
  2766. };
  2767.  
  2768. UI.skins["缺省皮肤".uiTrans()] = "";
  2769. UI.skins["暗色皮肤".uiTrans()] = "body { color: #666; background: rgba(0;0;0;.1); }\
  2770. .title { color: #222; }";
  2771. UI.skins["白底黑字".uiTrans()] = "body { color: black; background: white;}\
  2772. .title { font-weight: bold; border-bottom: 0.1em solid; margin-bottom: 1.857em; padding-bottom: 0.857em;}";
  2773. UI.skins["夜间模式".uiTrans()] = "body { color: #939392; background: #2d2d2d; } #preferencesBtn { background: white; } #mynovelreader-content img { background-color: #c0c0c0; }";
  2774. UI.skins["夜间模式1".uiTrans()] = "body { color: #679; background: black; } #preferencesBtn { background: white; }";
  2775. UI.skins["夜间模式2".uiTrans()] = "body { color: #e3e3e3; background: #2d2d2d; } #preferencesBtn { background: white; }";
  2776. // UI.skins["夜间模式(多看)".uiTrans()] = "body { color: #3A5056; background: #101819; } #preferencesBtn { background: white; } #mynovelreader-content img { background-color: #c0c0c0; }";
  2777. UI.skins["夜间模式(多看)".uiTrans()] = "body { color: #4A4A4A; background: #101819; } #preferencesBtn { background: white; } #mynovelreader-content img { background-color: #c0c0c0; }";
  2778. UI.skins["橙色背景".uiTrans()] = "body { color: #24272c; background: #FEF0E1; }";
  2779. UI.skins["绿色背景".uiTrans()] = "body { color: black; background: #d8e2c8; }";
  2780. UI.skins["绿色背景2".uiTrans()] = "body { color: black; background: #CCE8CF; }";
  2781. UI.skins["蓝色背景".uiTrans()] = "body { color: black; background: #E7F4FE; }";
  2782. UI.skins["棕黄背景".uiTrans()] = "body { color: black; background: #C2A886; }";
  2783. UI.skins["经典皮肤".uiTrans()] = "body { color: black; background-color: #EAEAEE; } .title { background: #f0f0f0; }";
  2784.  
  2785.  
  2786. var fontawesomeWoff = GM_getResourceURL('fontawesomeWoff');
  2787. if (!fontawesomeWoff || fontawesomeWoff.length < 10) {
  2788. fontawesomeWoff = "http://libs.baidu.com/fontawesome/4.0.3/fonts/fontawesome-webfont.woff?v=4.0.3";
  2789. } else if (isChrome) {
  2790. fontawesomeWoff = "data:font/woff;charset=utf-8;base64," + fontawesomeWoff;
  2791. }
  2792.  
  2793. var Res = {
  2794. CSS_MAIN: '@font-face {\n font-family: "FontAwesome";\n src: url({fontawesomeWoff});\n font-weight: normal;\n font-style: normal;\n}\nbody > a { display:none !important; }\n.hidden {\n display: none;\n}\n.quiet-mode {\n display: none;\n}\nbody {\n background: #F3F2EE;\n color: #1F0909;\n padding: 0px;\n margin: 0px;\n font-family: "Microsoft YaHei UI", 微软雅黑, 新宋体, 宋体, arial;\n}\na { color: #065488; }\na:link { text-decoration: none; }\n#mynovelreader-content {\n width: {content_width};\n font-size: {font_size};\n font-family: {font_family};\n line-height: {text_line_height};\n margin-left:auto;\n margin-right:auto;\n padding-bottom: 15px;\n}\narticle {\n margin-top: 55px;\n word-wrap: break-word;\n}\narticle h1 {\n clear: both;\n line-height: 50px;\n font-size: {title_font_size};\n font-weight: normal;\n margin: 25px -20px;\n padding: 0 20px 10px;\n border-bottom: 1px solid rgba(0,0,0,.25);\n font-weight: normal;\n text-transform: none;\n}\n.chapter-footer-nav {\n text-align:center;\n font-size:0.9em;\n margin:-10px 0px 30px 0px;\n}\n#loading {\n color: white;\n text-align: center;\n font: 12px "微软雅黑", "宋体", "Times New Roman", "Verdana";\n margin-top: 20px;\n margin-left: auto;\n margin-right: auto;\n width: 376px;\n height: 32px;\n line-height: 32px;\n border-radius: 20px;\n border: 1px solid #666;\n background-color: #333;\n}\n#loading img {\n vertical-align: middle;\n}\n#loading a {\n color: white;\n}\n#preferencesBtn{\n position: fixed;\n top: 10px;\n right: 10px;\n z-index: 1597;\n}\n#alert {\n position: fixed;\n z-index: 100;\n float: auto;\n width: auto;\n height: auto;\n top: 10px;\n left: 500px;\n background: rgba(215, 240, 253, 0.65);\n color: #2d7091;\n border: 1px solid rgba(45,112,145,0.3);\n border-radius: 4px;\n text-shadow: 0 1px 0 #fff;\n}\n#alert p {\n font-size: 13px;\n margin: 6px;\n}\nimg.blockImage {clear: both;float: none;display: block;margin-left: auto;margin-right: auto;}\n#menu-bar {\n border: solid rgba(0, 100, 255, .9);\n border-width: 3px 2px 3px 0px;\n position: fixed;\n left: 0px;\n top: 40%;\n height: 100px;\n width: 2px;\n z-index: 199;\n {menu-bar-hidden}\n}\n#menu-bar { \n top: 0px;\n height: 100%;\n width: 1px;\n background: transparent;\n border: none;\n}\n#menu {\n position: fixed;\n top: 0;\n bottom: 0;\n left: 0;\n z-index: 100;\n width: 270px;\n max-width: 100%;\n background: #333;\n overflow-y: auto;\n}\n#menu:after {\n content: "";\n display: block;\n position: absolute;\n top: 46px;\n bottom: 0;\n right: 0;\n width: 1px;\n background: rgba(0,0,0,0.6);\n box-shadow: 0 0 5px 2px rgba(0,0,0,0.6);\n}\n#header{\n color: #777;\n margin-top: 0;\n border-top: 1px solid rgba(0,0,0,0.3);\n background: #404040;\n box-shadow: inset 0 1px 0 rgba(255,255,255,0.05);\n text-shadow: 0 1px 0 rgba(0,0,0,0.5);\n padding: 10px 12px;\n text-transform: uppercase;\n font-weight: bold;\n font-size: 20px;\n}\n#header a {\n color: #777777;\n}\n#divider {\n position: relative;\n z-index: 300;\n border-top: 1px solid rgba(255,255,255,0.01);\n border-bottom: 1px solid rgba(0,0,0,0.3);\n margin: 0;\n height: 4px;\n background: rgba(0,0,0,0.2);\n box-shadow: 0 1px 0 rgba(255,255,255,0.05), inset 0 1px 3px rgba(0,0,0,0.3);\n}\n#chapter-list {\n position: relative;\n bottom: 0;\n left: 0;\n right: 0;\n z-index: 200;\n margin: 0;\n padding: 0;\n cursor: pointer;\n list-style: none;\n overflow-y: auto;\n}\n.chapter {\n list-style: none;\n}\n.chapter:last-child {\n border-bottom: 1px solid rgba(0,0,0,0.3);\n box-shadow: 0 1px 0 rgba(255,255,255,0.05);\n}\n.chapter div {\n color: #ccc;\n font-size: 15px;\n padding: 8px 20px;\n border-top: 1px solid rgba(0,0,0,0.3);\n box-shadow: inset 0 1px 0 rgba(255,255,255,0.05);\n text-shadow: 0 1px 0 rgba(0,0,0,0.5);\n display: block;\n text-decoration: none;\n text-overflow: ellipsis;\n overflow: hidden;\n white-space: nowrap;\n cursor: pointer;\n}\n.chapter div:before {\n content: "\\f105";\n width: 20px;\n margin-left: -10px;\n float: left;\n font-family: "FontAwesome" !important;\n text-align: center;\n}\n.chapter div:hover {\n background: #404040;\n color: #fff;\n outline: 0;\n}\n.chapter.active div {\n background: #1a1a1a;\n color: #fff;\n font-size: 16px;\n box-shadow: inset 0 1px 3px rgba(0,0,0,0.3);\n}\n::-webkit-scrollbar {\n height: 9px !important;\n width: 9px !important;\n}\n::-webkit-scrollbar-thumb {\n background-color: #7D7D7D !important;\n border-radius: 3px !important;\n}\n::-webkit-scrollbar-track-piece {\n background-color: rgba(0,0,0,.25) !important;\n}'
  2795. .replace('{fontawesomeWoff}', fontawesomeWoff),
  2796.  
  2797. 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 </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 <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>'
  2798. .uiTrans().replace(/\\n/g, '\n'),
  2799.  
  2800. preferencesCSS: '.body {\n color:#333;\n margin: 0 auto;\n background: white;\n padding: 10px;\n height: 420px;\n overflow-y: auto;\n }\n #top-buttons {\n background: none repeat scroll 0% 0% rgb(255, 255, 255);\n display: block;\n position: absolute;\n top: -35px;\n border-right: 12px solid rgb(224, 224, 224);\n border-top: 12px solid rgb(224, 224, 224);\n border-left: 12px solid rgb(224, 224, 224);\n text-align: center;\n }\n input {\n font-size: 12px;\n margin-right: 3px;\n vertical-align: middle;\n }\n .form-row {\n overflow: hidden;\n padding: 8px 12px;\n margin-top: 3px;\n font-size: 11px;\n }\n .form-row label {\n padding-right: 10px;\n }\n .form-row input {\n vertical-align: middle;\n margin-top: 0px;\n }\n textarea, .form-row input {\n padding: 2px 4px;\n border: 1px solid #e5e5e5;\n background: #fff;\n border-radius: 4px;\n color: #666;\n -webkit-transition: all linear .2s;\n transition: all linear .2s;\n }\n textarea {\n width: 100%;\n overflow: auto;\n vertical-align: top;\n }\n textarea:focus, input:focus {\n border-color: #99baca;\n outline: 0;\n background: #f5fbfe;\n color: #666;\n }\n .prefs_title {\n font-size: 12px;\n font-weight: bold;\n }\n .prefs_textarea {\n font-size: 12px;\n margin-top: 5px;\n height: 100px;\n }\n .right {\n float: right;\n }',
  2801. };
  2802.  
  2803.  
  2804. function Parser(){
  2805. this.init.apply(this, arguments);
  2806. }
  2807.  
  2808. Parser.prototype = {
  2809. constructor: Parser,
  2810. get contentTxt() { // callback 才有用
  2811. // textContent 第二段不对劲会被合并到第一段?
  2812. return $('<div>').html(this.content).text().trim();
  2813. },
  2814.  
  2815. init: function (info, doc, curPageUrl) {
  2816. this.info = info || {};
  2817. this.doc = doc;
  2818. this.$doc = $(doc);
  2819. this.curPageUrl = curPageUrl || doc.URL;
  2820. this._curPageHost = getUrlHost(this.curPageUrl); // 当前页的 host,后面用到
  2821.  
  2822. // 设置初始值
  2823. this.isTheEnd = false;
  2824. this.isSection = false;
  2825.  
  2826. C.debug('开始解析页面');
  2827.  
  2828. this.applyPatch();
  2829. },
  2830. applyPatch: function(){
  2831. var contentPatch = this.info.contentPatch;
  2832. if(contentPatch){
  2833. try {
  2834. contentPatch(this.$doc);
  2835. C.log("Apply Content Patch Success.");
  2836. } catch (e) {
  2837. C.log("Error: Content Patch Error!", e);
  2838. }
  2839. }
  2840. },
  2841. hasContent: function() {
  2842. var $content;
  2843.  
  2844. // var $ajaxScript = this.$doc.find('.' + READER_AJAX);
  2845. // if ($ajaxScript.length > 0) {
  2846. // return true;
  2847. // }
  2848.  
  2849. if(this.info.contentSelector){
  2850. $content = this.$doc.find(this.info.contentSelector);
  2851. }
  2852.  
  2853. if (!$content || !$content.length) {
  2854. // 按照顺序选取
  2855. var selectors = Rule.contentSelectors;
  2856. for(var i = 0, l = selectors.length; i < l; i++){
  2857. $content = this.$doc.find(selectors[i]);
  2858. if($content.length){
  2859. C.log("自动查找内容选择器: " + selectors[i]);
  2860. break;
  2861. }
  2862. }
  2863. }
  2864.  
  2865. this.$content = $content;
  2866. C.debug($content);
  2867.  
  2868. return $content.size() > 0;
  2869. },
  2870. getAll: function(callback){
  2871.  
  2872. C.group('开始获取链接');
  2873. this.getPrevUrl();
  2874. this.getIndexUrl();
  2875. this.getNextUrl();
  2876. C.groupEnd();
  2877.  
  2878. C.group('开始获取标题');
  2879. this.getTitles();
  2880. C.groupEnd();
  2881.  
  2882. this.getContent(callback);
  2883.  
  2884. return this;
  2885. },
  2886.  
  2887. // 获取书名和章节标题
  2888. getTitles: function(){
  2889. var info = this.info,
  2890. chapterTitle,
  2891. bookTitle,
  2892. docTitle = this.$doc.find("title").text();
  2893.  
  2894. // 获取章节标题
  2895. if (info.titleReg){
  2896. var matches = docTitle.match(toRE(info.titleReg, 'i'));
  2897. if(matches && matches.length == 3){
  2898. var titlePos = ( info.titlePos || 0 ) + 1,
  2899. chapterPos = (titlePos == 1) ? 2 : 1;
  2900. bookTitle = matches[titlePos].trim();
  2901. chapterTitle = matches[chapterPos].trim();
  2902. }
  2903.  
  2904. C.log("TitleReg:", info.titleReg, matches);
  2905. } else {
  2906. chapterTitle = this.getTitleFromInfo(info.titleSelector);
  2907.  
  2908. bookTitle = this.getTitleFromInfo(info.bookTitleSelector);
  2909. }
  2910.  
  2911. if(!chapterTitle){
  2912. chapterTitle = this.autoGetChapterTitle(this.doc);
  2913. }
  2914.  
  2915. if (!bookTitle) {
  2916. bookTitle = this.$doc.find(Rule.bookTitleSelector).text();
  2917. }
  2918.  
  2919. // 标题间增加一个空格,不准确,已注释
  2920. chapterTitle = chapterTitle
  2921. .replace(Rule.titleReplace, "")
  2922. .trim();
  2923. // .replace(/(第?\S+?[章节卷回])(.*)/, "$1 $2");
  2924.  
  2925. // if (info.trimBookTitle !== false) {
  2926. // chapterTitle = chapterTitle.replace(bookTitle, '').trim();
  2927. // }
  2928.  
  2929. bookTitle = bookTitle.replace(/最新章节$/, '');
  2930.  
  2931. docTitle = bookTitle ?
  2932. bookTitle + ' - ' + chapterTitle :
  2933. docTitle;
  2934.  
  2935. if (Config.cn2tw) {
  2936. bookTitle = this.convert2tw(bookTitle);
  2937. chapterTitle = this.convert2tw(chapterTitle);
  2938. docTitle = this.convert2tw(docTitle);
  2939. }
  2940.  
  2941. this.bookTitle = bookTitle || '目录';
  2942. this.chapterTitle = chapterTitle;
  2943. this.docTitle = docTitle;
  2944.  
  2945. C.log("Book Title: " + this.bookTitle);
  2946. C.log("Chapter Title: " + this.chapterTitle);
  2947. C.log("Document Title: " + this.docTitle);
  2948. },
  2949. getTitleFromInfo: function(selectorOrArray) {
  2950. var title = '';
  2951. if (!selectorOrArray) {
  2952. return title;
  2953. }
  2954.  
  2955. var selector,
  2956. replace;
  2957.  
  2958. if (_.isArray(selectorOrArray)) {
  2959. selector = selectorOrArray[0];
  2960. replace = selectorOrArray[1];
  2961. } else {
  2962. selector = selectorOrArray;
  2963. }
  2964.  
  2965. title = this.$doc.find(selector).remove().text().trim();
  2966.  
  2967. if (replace) {
  2968. title = title.replace(toRE(replace), '');
  2969. }
  2970.  
  2971. return title;
  2972. },
  2973. // 智能获取章节标题
  2974. autoGetChapterTitle: function (document) {
  2975. var
  2976. _main_selector = "h1, h2, h3",
  2977. _second_selector = "#TextTitle, #title, .ChapterName, #lbChapterName, div.h1",
  2978. _positive_regexp = Rule.titleRegExp,
  2979. // _positive_regexp = /第?\S+[章节卷回]|\d{2,4}/,
  2980. // _negative_regexp = /[上前下后][一]?[页张个篇章节步]/,
  2981. _title_remove_regexp = /最新章节|书书网/,
  2982. $doc = $(document),
  2983. _document_title = document.title ? document.title : $doc.find("title").text(),
  2984. _search_document_title = ' ' + _document_title.replace(/\s+/gi, ' ') + ' '
  2985. ;
  2986.  
  2987. var _headings = $doc.find(_main_selector);
  2988. // 加上 second selector 并去除包含的
  2989. $doc.find(_second_selector).each(function(){
  2990. if($(this).find(_main_selector).length === 0){
  2991. _headings.push(this);
  2992. }
  2993. });
  2994.  
  2995. var possibleTitles = {},
  2996. _heading_text;
  2997.  
  2998. C.groupCollapsed('自动查找章节标题');
  2999.  
  3000. $(_headings).each(function(){
  3001. var _heading = this,
  3002. _heading_text = _heading.textContent.trim();
  3003.  
  3004. if (_heading_text in possibleTitles) {
  3005. return;
  3006. }
  3007.  
  3008. C.group('开始计算 "' + _heading_text + '" 的得分');
  3009.  
  3010. // h1 为 1, h2 为 2
  3011. var
  3012. nodeNum = parseInt(_heading.nodeName.slice(1), 10) || 10,
  3013. score = 10 / nodeNum,
  3014. _heading_words = _heading_text.replace(/\s+/g, " ").split(" "),
  3015. _matched_words = ""
  3016. ;
  3017.  
  3018. C.log("初始得分:" + score);
  3019.  
  3020. // 后面这种是特殊的判断
  3021. if (_positive_regexp.test(_heading_text) || /\d{2,4}/.test(_heading_text)) {
  3022. score += 50;
  3023. }
  3024. // if(_negative_regexp.test(_heading_text)){
  3025. // score -= 100;
  3026. // }
  3027.  
  3028. C.log("符合正则计算后得分:" + score);
  3029.  
  3030. // count words present in title
  3031. for (var j = 0, _j = _heading_words.length; j < _j; j++) {
  3032. if (_search_document_title.indexOf(_heading_words[j]) > -1) {
  3033. _matched_words += _heading_words[j] + ' ';
  3034. }
  3035. }
  3036. score += _matched_words.length * 1.5;
  3037.  
  3038. C.log("跟页面标题比较后得分:" + score);
  3039.  
  3040. var _font_size_text = "",
  3041. _font_size_add_score = 0,
  3042. _heading_style = window.getComputedStyle(_heading, null);
  3043. if(_heading_style){
  3044. _font_size_text = _heading_style.getPropertyValue("font-size") || 0;
  3045. _font_size_add_score = parseInt(_font_size_text, 10) * 1.5;
  3046. }
  3047.  
  3048. score += _font_size_add_score;
  3049.  
  3050. C.log("计算大小后得分:" + score);
  3051.  
  3052. possibleTitles[_heading_text] = score;
  3053.  
  3054. C.groupEnd();
  3055. });
  3056.  
  3057. // 找到分数最高的值
  3058. var topScoreTitle,
  3059. score_tmp = 0;
  3060. for (_heading_text in possibleTitles) {
  3061. if (possibleTitles[_heading_text] > score_tmp) {
  3062. topScoreTitle = _heading_text;
  3063. score_tmp = possibleTitles[_heading_text];
  3064. }
  3065. }
  3066.  
  3067. var curTitle = topScoreTitle;
  3068. if (!curTitle) {
  3069. curTitle = _document_title;
  3070.  
  3071. // 下面的正则从
  3072. // Firefox-Firefox浏览器论坛-卡饭论坛 - 互助分享 - 大气谦和!
  3073. // 变为
  3074. // Firefox-Firefox浏览器论坛-卡饭论坛
  3075. curTitle = curTitle.replace(/\s-\s.*/i, "")
  3076. .replace(/_[^\[\]【】]+$/, "");
  3077. curTitle = curTitle.trim();
  3078. curTitle = curTitle.replace(_title_remove_regexp, '');
  3079. }
  3080.  
  3081. curTitle = curTitle.replace(Rule.titleReplace, "");
  3082.  
  3083. C.groupEnd();
  3084.  
  3085. return curTitle;
  3086. },
  3087.  
  3088. // 获取和处理内容
  3089. getContent: function(callback){
  3090. if(_.isUndefined(callback)){
  3091. callback = function() {};
  3092. }
  3093.  
  3094. if (!this.$content) {
  3095. this.hasContent();
  3096. }
  3097.  
  3098. if (this.$content.size() <= 0) {
  3099. callback(this);
  3100. return;
  3101. }
  3102.  
  3103. // 特殊处理,例如起点
  3104. var self = this;
  3105. var ajaxScript = this.$doc.find('.' + READER_AJAX);
  3106. if(ajaxScript.length > 0){
  3107. var url = ajaxScript.attr('src');
  3108. if(!url) return;
  3109. var charset = ajaxScript.attr('charset') || 'utf-8';
  3110.  
  3111. C.log('Ajax 获取内容: ', url, ". charset=" + charset);
  3112.  
  3113. var reqObj = {
  3114. url: url,
  3115. method: "GET",
  3116. overrideMimeType: "text/html;charset=" + charset,
  3117. headers: {},
  3118. onload: function(res){
  3119. var text = res.responseText;
  3120. if (text.indexOf('{"CID":') === 0) { // 创世中文
  3121. text = JSON.parse(text).Content;
  3122. text = $('<div>').html(text).find('.bookreadercontent').html();
  3123. } else {
  3124. text = text.replace(/document.write(ln)?\('/, "")
  3125. .replace("');", "")
  3126. .replace(/[\n\r]+/g, '</p><p>');
  3127. }
  3128.  
  3129. self.content = self.handleContentText(text, self.info);
  3130. callback(self);
  3131. }
  3132. };
  3133.  
  3134. // Jixun: Allow post data
  3135. var postData = ajaxScript.data('post');
  3136.  
  3137. if (postData) {
  3138. reqObj.method = 'POST';
  3139. reqObj.data = $.param(postData);
  3140. reqObj.headers['Content-Type'] = 'application/x-www-form-urlencoded';
  3141. }
  3142.  
  3143. GM_xmlhttpRequest(reqObj);
  3144. }else{
  3145. this.content = this.handleContentText(this.$content.html(), this.info);
  3146. callback(this);
  3147. }
  3148. },
  3149. handleContentText: function(text, info){
  3150. if(!text) return null;
  3151.  
  3152. // 贴吧的内容处理比较耗时间
  3153. C.group('开始内容处理');
  3154. C.time('内容处理');
  3155.  
  3156. var contentHandle = (typeof(info.contentHandle) == 'undefined') ? true : info.contentHandle;
  3157.  
  3158. // 拼音字、屏蔽字修复
  3159. if(contentHandle){
  3160. text = this.replaceHtml(text);
  3161. }
  3162.  
  3163. /* Turn all double br's into p's */
  3164. text = text.replace(Rule.replaceBrs, '</p>\n<p>');
  3165. text = text.replace(/<\/p><p>/g, "</p>\n<p>");
  3166.  
  3167. // GM_setClipboard(text);
  3168.  
  3169. if (info.contentReplace) {
  3170. text = this.replaceText(text, info.contentReplace);
  3171. }
  3172.  
  3173. // 去除内容中的标题
  3174. if(this.chapterTitle && Rule.titleRegExp.test(this.chapterTitle)){
  3175. try {
  3176. var reg = toReStr(this.chapterTitle).replace(/\s+/g, '\\s*');
  3177. reg = new RegExp(reg, 'ig');
  3178. text = text.replace(reg, "");
  3179. C.log('去除内容中的标题', reg);
  3180. } catch(e) {
  3181. console.error(e);
  3182. }
  3183. }
  3184.  
  3185. if (this.bookTitle) {
  3186. var regStr = '(' + toReStr(this.bookTitle) + '\\d*章)'
  3187. text = text.replace(new RegExp(regStr, 'ig'), "");
  3188. }
  3189.  
  3190. text = text.replace(Rule.contentReplace, '');
  3191.  
  3192. if (Config.cn2tw) {
  3193. text = this.convert2tw(text);
  3194. }
  3195.  
  3196. try {
  3197. text = this.contentCustomReplace(text);
  3198. } catch(ex) {
  3199. console.error('自定义替换错误', ex);
  3200. }
  3201.  
  3202. // 采用 DOM 方式进行处理
  3203. var $div = $("<div>").html(text);
  3204.  
  3205. // contentRemove
  3206. $div.find(Rule.contentRemove).remove();
  3207. if(info.contentRemove){
  3208. $div.find(info.contentRemove).remove();
  3209. }
  3210.  
  3211. // 给独立的文本加上 p
  3212. $div.contents().filter(function() {
  3213. return this.nodeType == 3 &&
  3214. this.textContent != '\n' &&
  3215. (!this.nextElementSibling || this.nextElementSibling.nodeName != 'A') &&
  3216. (!this.previousElementSibling || this.previousElementSibling.nodeName != 'A');
  3217. }).wrap('<p>');
  3218.  
  3219. // 删除无效的 p,排除对大块文本的判断
  3220. $div.find('p').filter(function() {
  3221. // 有效文本(排除注释、换行符、空白)个数为 0
  3222. return $(this).contents().filter(function() {
  3223. return this.nodeType != 8 &&
  3224. !this.textContent.match(/^\s*$/);
  3225. }).size() == 0;
  3226. }).remove();
  3227.  
  3228. // 把一大块的文本分段
  3229. if (Config.split_content) {
  3230. var $p = $div.find('p'),
  3231. $newP;
  3232. if ($p.length == 0 ) {
  3233. $newP = $div;
  3234. } else if ($p.length == 1) {
  3235. $newP = $p;
  3236. }
  3237.  
  3238. if ($newP) {
  3239. $newP.replaceWith('<p>' + this.splitContent($newP.html()).join('</p>\n<p>') + '</p>');
  3240. }
  3241. }
  3242.  
  3243. if(contentHandle){
  3244. $div.filter('br').remove();
  3245.  
  3246. $div.find('*').removeAttr('style');
  3247. }
  3248.  
  3249. $div.find('p').removeAttr('class');
  3250.  
  3251. // 图片居中,所有图像?
  3252. // if(info.fixImage){
  3253. // $div.find("img").each(function(){
  3254. // this.className += " blockImage";
  3255. // });
  3256. // }
  3257.  
  3258. text = $div.html();
  3259.  
  3260. // 修复第一行可能是空的情况
  3261. text = text.replace(/(?:\s|&nbsp;)+<p>/, "<p>");
  3262.  
  3263. // 修复当行就一个字符的
  3264. text = text.replace(/<\/p><p>([。])/, "$1");
  3265.  
  3266. if(config.paragraphBlank){
  3267. text = text.replace(/<p>(?:\s|&nbsp;)+/g, "<p>")
  3268. .replace(/<p>/g, "<p>  ");
  3269. }
  3270.  
  3271. // 删除空白的、单个字符的 p
  3272. text = text.replace(Rule.removeLineRegExp, "");
  3273.  
  3274. C.timeEnd('内容处理');
  3275. C.groupEnd();
  3276.  
  3277. return text;
  3278. },
  3279. replaceHtml: function(text, replaceRule) { // replaceRule 给“自定义替换规则直接生效”用
  3280. // 先提取出 img
  3281. var imgs = {};
  3282. var i = 0;
  3283. text = text.replace(/<(img|a)[^>]*>/g, function(img){
  3284. imgs[i] = img;
  3285. return "{" + (i++) + "}";
  3286. });
  3287.  
  3288. if (!replaceRule) {
  3289. // 移除文字广告等
  3290. text = this.replaceText(text, Rule.replaceAll);
  3291. replaceRule = Rule.replace;
  3292. }
  3293.  
  3294. // 修正拼音字等
  3295. text = this.contentReplacements(text, replaceRule);
  3296.  
  3297. // 还原图片
  3298. text = $.nano(text, imgs);
  3299.  
  3300. return text;
  3301. },
  3302. contentReplacements: function (text, rule) {
  3303. if (!text) return text;
  3304.  
  3305. for (var key in rule) {
  3306. text = text.replace(toRE(key, "ig"), rule[key]);
  3307. }
  3308. return text;
  3309. },
  3310. replaceText: function(text, rule){
  3311. var self = this;
  3312. switch(true) {
  3313. case _.isRegExp(rule):
  3314. text = text.replace(rule, '');
  3315. break;
  3316. case _.isString(rule):
  3317. var regexp = new RegExp(rule, 'ig');
  3318. text = text.replace(regexp, '');
  3319. break;
  3320. case _.isArray(rule):
  3321. rule.forEach(function(r){
  3322. text = self.replaceText(text, r);
  3323. });
  3324. break;
  3325. case _.isObject(rule):
  3326. var key;
  3327. for(key in rule){
  3328. text = text.replace(new RegExp(key, "ig"), rule[key]);
  3329. }
  3330. break;
  3331. }
  3332. return text;
  3333. },
  3334. convert2tw: function (text) {
  3335. if (!text) return text;
  3336.  
  3337. var ii, len, str;
  3338. str = text.split("");
  3339. len = str.length;
  3340. for (ii = 0; ii < len; ii++) {
  3341. str[ii] = cn2tw[str[ii]] || str[ii];
  3342. }
  3343.  
  3344. str = str.join("");
  3345.  
  3346. return str;
  3347. },
  3348. contentCustomReplace: function (text) {
  3349. if (!text) return text;
  3350.  
  3351. for (var key in Rule.customReplace) {
  3352. text = text.replace(new RegExp(key, 'ig'), Rule.customReplace[key]);
  3353. }
  3354. return text;
  3355. },
  3356. splitContent: function (text) { // 有些章节整个都集中在一起,没有分段,整个函数用于简易分段
  3357. if (text.indexOf('。') == -1) {
  3358. return [text];
  3359. }
  3360.  
  3361. var hasMark = false,
  3362. lines = []
  3363. charCotainer = [];
  3364.  
  3365. text.split('').forEach(function(c) {
  3366. charCotainer.push(c);
  3367.  
  3368. if (c == '“') {
  3369. hasMark = true;
  3370. } else if (c == '”') {
  3371. hasMark = false;
  3372. } else if (c == '。' && !hasMark) {
  3373. lines.push(charCotainer.join(''));
  3374. charCotainer = [];
  3375. }
  3376. });
  3377.  
  3378. return lines;
  3379. },
  3380.  
  3381. // 获取上下页及目录页链接
  3382. getPrevUrl: function(){
  3383. var url = '',
  3384. link, selector;
  3385.  
  3386. if (this.info.prevSelector === false) {
  3387. this.prevUrl = url;
  3388. return url;
  3389. }
  3390.  
  3391. if (this.info.prevUrl && _.isFunction(this.info.prevUrl)) {
  3392. url = this.info.prevUrl(this.$doc);
  3393. url = this.checkLinks(url);
  3394. }
  3395.  
  3396. if (!url) {
  3397. selector = this.info.prevSelector || Rule.prevSelector;
  3398. link = this.$doc.find(selector);
  3399. if(link.length){
  3400. url = this.checkLinks(link);
  3401. }
  3402. }
  3403.  
  3404. if (url) {
  3405. C.log("找到上一页链接: " + url);
  3406. } else {
  3407. C.log("无法找到上一页链接");
  3408. }
  3409.  
  3410. this.prevUrl = url || '';
  3411. return url;
  3412. },
  3413. getIndexUrl: function(){
  3414. var url = '',
  3415. link;
  3416.  
  3417. if (this.info.indexSelector === false) {
  3418. this.indexUrl = url;
  3419. return url;
  3420. }
  3421.  
  3422. if(this.info.indexSelector){
  3423. link = this.$doc.find(this.info.indexSelector);
  3424. }else{
  3425. var selectors = Rule.indexSelectors;
  3426. var _indexLink;
  3427. // 按照顺序选取目录链接
  3428. for(var i = 0, l = selectors.length; i < l; i++){
  3429. _indexLink = this.$doc.find(selectors[i]);
  3430. if(_indexLink.length > 0){
  3431. link = _indexLink;
  3432. break;
  3433. }
  3434. }
  3435. }
  3436.  
  3437. if(link && link.length){
  3438. url = this.checkLinks(link);
  3439. C.log("找到目录链接: " + url);
  3440. }else{
  3441. C.log("无法找到目录链接.");
  3442. }
  3443.  
  3444. this.indexUrl = url;
  3445. return url;
  3446. },
  3447. getNextUrl: function(){
  3448. var url = '',
  3449. link,
  3450. selector = this.info.nextSelector || Rule.nextSelector;
  3451.  
  3452. if (this.info.nextSelector === false) {
  3453. this.nextUrl = url;
  3454. return url;
  3455. }
  3456.  
  3457. if (this.info.nextUrl && _.isFunction(this.info.nextUrl)) {
  3458. url = this.info.nextUrl(this.$doc);
  3459. url = this.checkLinks(url);
  3460. }
  3461.  
  3462. if (!url) {
  3463. link = this.$doc.find(selector);
  3464. if(link.length){
  3465. url = this.checkLinks(link);
  3466. }
  3467. }
  3468.  
  3469. if (url) {
  3470. C.log("找到下一页链接: " + url);
  3471. } else {
  3472. C.log("无法找到下一页链接");
  3473. }
  3474.  
  3475. this.nextUrl = url || '';
  3476. this.isTheEnd = !this.checkNextUrl(url);
  3477. if(this.isTheEnd){
  3478. this.theEndColor = config.end_color;
  3479. }
  3480.  
  3481. return url;
  3482. },
  3483. checkNextUrl: function(url){
  3484. if (this.info.checkSection) {
  3485. if (/\/\d+_\d+\.html$/.test(this.curPageUrl)) {
  3486. this.isSection = true;
  3487. if(url == this.indexUrl){
  3488. return false;
  3489. }else{
  3490. return true;
  3491. }
  3492. }
  3493. }
  3494.  
  3495. switch(true){
  3496. case url === '':
  3497. case Rule.nextUrlIgnore.some(function(re) { return toRE(re).test(url) }):
  3498. case url === this.indexUrl:
  3499. case url === this.prevUrl:
  3500. case url === this.curPageUrl:
  3501. case Rule.nextUrlCompare.test(this.prevUrl) && !Rule.nextUrlCompare.test(url):
  3502. return false;
  3503. default:
  3504. return true;
  3505. }
  3506. },
  3507. checkLinks: function(links){
  3508. var self = this;
  3509. if (_.isString(links)) {
  3510. return this.getFullHref(links);
  3511. }
  3512.  
  3513. var url = "";
  3514. links && links.each(function(){
  3515. url = $(this).attr("href");
  3516. if(!url || url.indexOf("#") === 0 || url.indexOf("javascript:") === 0)
  3517. return;
  3518.  
  3519. url = self.getFullHref(this);
  3520. return false;
  3521. });
  3522.  
  3523. return url;
  3524. },
  3525. getLinkUrl: function(linkOrUrl) {
  3526. // if (linkOrUrl && )
  3527. return linkOrUrl;
  3528. },
  3529. getFullHref: function(href) {
  3530. if(!href) return '';
  3531.  
  3532. if (!_.isString(href)) {
  3533. href = href.getAttribute('href');
  3534. }
  3535.  
  3536. if (href.indexOf('http://') === 0) {
  3537. return href;
  3538. }
  3539.  
  3540. var a = this.a;
  3541. if (!a) {
  3542. this.a = a = document.createElement('a');
  3543. }
  3544. a.href = href;
  3545.  
  3546. // 检测 host 是否和 当前页的一致
  3547. if (a.host != this._curPageHost) {
  3548. a.host = this._curPageHost;
  3549. }
  3550.  
  3551. return a.href;
  3552. },
  3553. };
  3554.  
  3555.  
  3556. var App = {
  3557. isEnabled: false,
  3558. parsedPages: {},
  3559. pageNum: 1,
  3560. paused: false,
  3561. curPageUrl: location.href,
  3562. requestUrl: null,
  3563. iframe: null,
  3564. remove: [],
  3565.  
  3566. init: function() {
  3567. if (["mynovelreader-iframe", "superpreloader-iframe"].indexOf(window.name) != -1) { // 用于加载下一页的 iframe
  3568. return;
  3569. }
  3570.  
  3571. // 手动调用
  3572. var readx = function() {
  3573. // 防止 unsafeWindow cannot call: GM_getValue
  3574. setTimeout(function() {
  3575. App.launch();
  3576. }, 0);
  3577. };
  3578. exportFunction(readx, unsafeWindow, {defineAs: "readx"});
  3579.  
  3580. App.loadCustomSetting();
  3581. App.site = App.getCurSiteInfo();
  3582. var autoLaunch = App.isAutoLaunch();
  3583.  
  3584. if (autoLaunch === -1) {
  3585. return;
  3586. } else if (autoLaunch) {
  3587. if (App.site.mutationSelector) { // 特殊的启动:等待js把内容生成完毕
  3588. App.addMutationObserve(document, App.launch);
  3589. } else if (App.site.timeout) { // 延迟启动
  3590. setTimeout(App.launch, App.site.timeout);
  3591. } else { // NoScript 下 setTimeout 没用?
  3592. App.launch();
  3593. }
  3594. } else {
  3595. UI.addButton();
  3596. }
  3597. },
  3598. loadCustomSetting: function() {
  3599. var customRules;
  3600. try {
  3601. customRules = eval(Config.customSiteinfo);
  3602. } catch (e) {
  3603. console.error('载入自定义站点配置错误', e);
  3604. }
  3605. if (_.isArray(customRules)) {
  3606. Rule.customRules = customRules;
  3607. C.log('载入自定义站点规则成功', customRules);
  3608. }
  3609.  
  3610. // load custom replace rules
  3611. Rule.customReplace = Rule.parseCustomReplaceRules(Config.customReplaceRules);
  3612.  
  3613. C.log('载入自定义替换规则成功', Rule.customReplace);
  3614. },
  3615. getCurSiteInfo: function() {
  3616. var rules = Rule.customRules.concat(Rule.specialSite);
  3617. var locationHref = location.href;
  3618.  
  3619. var info = _.find(rules, function(x) {
  3620. return toRE(x.url).test(locationHref);
  3621. });
  3622. if (!info) {
  3623. info = {};
  3624. C.log("没有找到规则,尝试自动模式。");
  3625. } else {
  3626. C.log("找到规则:", info);
  3627. }
  3628. return info;
  3629. },
  3630. isAutoLaunch: function() {
  3631. var locationHref = window.location.href,
  3632. locationHost = location.host,
  3633. referrer = document.referrer;
  3634. switch (true) {
  3635. case L_getValue("mynoverlreader_disable_once") == 'true':
  3636. L_removeValue("mynoverlreader_disable_once");
  3637. return false;
  3638. // case location.hostname == 'www.fkzww.net' && !document.title.match(/网文快讯/): // 啃书只自动启用一个地方
  3639. // return false;
  3640. case Config.booklink_enable && /booklink\.me/.test(referrer):
  3641. return true;
  3642. case locationHost == 'tieba.baidu.com':
  3643. var title = $('.core_title_txt').text();
  3644. if (title.match(Rule.titleRegExp)) {
  3645. return false;
  3646. } else {
  3647. return -1;
  3648. }
  3649. case Config.getDisableAutoLaunch():
  3650. return false;
  3651. case GM_getValue("auto_enable"):
  3652. case config.soduso && /www\.sodu\.so/.test(referrer):
  3653. return true;
  3654. default:
  3655. return false;
  3656. }
  3657. },
  3658. addMutationObserve: function(doc, callback) {
  3659. var shouldAdd = false;
  3660. var selector = App.site.mutationSelector;
  3661. var target = $(doc).find(selector)[0];
  3662. if (target) {
  3663. var childCount = App.site.mutationChildCount;
  3664. if (childCount === undefined || target.children.length <= childCount) {
  3665. shouldAdd = true;
  3666. }
  3667. }
  3668.  
  3669. if (shouldAdd) {
  3670. var observer = new MutationObserver(function(mutations) {
  3671. var nodeAdded = mutations.some(function(x) {
  3672. return x.addedNodes.length > 0;
  3673. });
  3674.  
  3675. if (nodeAdded) {
  3676. observer.disconnect();
  3677. callback();
  3678. }
  3679. });
  3680.  
  3681. observer.observe(target, {
  3682. childList: true
  3683. });
  3684.  
  3685. C.log("添加 MutationObserve 成功:", selector);
  3686. } else {
  3687. callback();
  3688. }
  3689. },
  3690. launch: function() {
  3691. // 只解析一次,防止多次重复解析一个页面
  3692. if (document.body && document.body.getAttribute("name") == "MyNovelReader") {
  3693. return App.toggle();
  3694. }
  3695.  
  3696. if (!App.site) {
  3697. App.site = App.getCurSiteInfo();
  3698. }
  3699.  
  3700. if (App.site.startFilter) {
  3701. try {
  3702. App.site.startFilter();
  3703. C.log('run startFilter function success');
  3704. } catch (ex) {
  3705. console.error('运行 startFilter function 错误', ex);
  3706. }
  3707. }
  3708.  
  3709. var parser = new Parser(App.site, document);
  3710. var hasContent = !!parser.hasContent();
  3711. if (hasContent) {
  3712. document.body.setAttribute("name", "MyNovelReader");
  3713. App.parsedPages[window.location.href] = true;
  3714. parser.getAll(function(parser) {
  3715. App.processPage(parser);
  3716. });
  3717. } else {
  3718. console.error("当前页面没有找到内容");
  3719. }
  3720.  
  3721. // 初始化, 取消页面限制等
  3722. if (App.site.fInit)
  3723. App.site.fInit();
  3724. },
  3725. processPage: function(parser) {
  3726. // 对 Document 进行处理
  3727. document.body.innerHTML = '';
  3728. App.prepDocument();
  3729. App.initDocument(parser);
  3730.  
  3731. // cache vars
  3732. App.$doc = $(document);
  3733. App.$menuBar = App.$doc.find("#menu-bar");
  3734. App.$menu = App.$doc.find("#menu");
  3735. App.$content = App.$doc.find("#mynovelreader-content");
  3736. App.$loading = App.$doc.find("#loading");
  3737. App.$preferencesBtn = App.$doc.find("#preferencesBtn");
  3738.  
  3739. App.$menuHeader = App.$menu.find("#chapter-list");
  3740. App.$chapterList = App.$menu.find("#chapter-list");
  3741.  
  3742. App.indexUrl = parser.indexUrl;
  3743. App.prevUrl = parser.prevUrl; // 第一个上一页
  3744.  
  3745. App.oArticles = []; // 原始的内容,用于替换的无需刷新
  3746. App.parsers = [];
  3747.  
  3748. // 加入上一章的链接
  3749. if (parser.prevUrl) {
  3750. $("<li>")
  3751. .addClass('chapter')
  3752. .append(
  3753. $("<div>")
  3754. .attr({
  3755. "realHref": parser.prevUrl,
  3756. "onclick": "return false;"
  3757. })
  3758. .text("上一章".uiTrans())
  3759. )
  3760. .prependTo(App.$chapterList);
  3761. }
  3762.  
  3763. // 插入站点样式
  3764. if (App.site.style) {
  3765. GM_addStyle(App.site.style);
  3766. }
  3767.  
  3768. App.appendPage(parser, true);
  3769.  
  3770. App.registerControls();
  3771.  
  3772. // UI 的初始化
  3773. UI.init();
  3774.  
  3775. App.curFocusElement = $("article:first").get(0); // 初始化当前关注的 element
  3776. App.requestUrl = parser.nextUrl;
  3777. App.isTheEnd = parser.isTheEnd;
  3778.  
  3779. App.isEnabled = true;
  3780. UI.addButton();
  3781.  
  3782. // // 如果已经把当前焦点链接添加到历史记录,则滚动到顶部
  3783. // if (Config.addToHistory) {
  3784. // window.scrollTo(0, 0);
  3785. // }
  3786.  
  3787. // 有些图片网站高度随着图片加载而变长
  3788. setTimeout(App.scroll, 1000);
  3789.  
  3790. App.cleanAgain();
  3791.  
  3792. if (config.PRELOADER) {
  3793. App.doRequest();
  3794. }
  3795. },
  3796. prepDocument: function() {
  3797. window.onload = window.onunload = function() {};
  3798.  
  3799. // 破解右键限制
  3800. var doc = document;
  3801. var bd = doc.body;
  3802. 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;
  3803. doc.onclick = doc.ondblclick = doc.onselectstart = doc.oncontextmenu = doc.onmousedown = doc.onkeydown = function() {
  3804. return true;
  3805. };
  3806.  
  3807. doc = document.wrappedJSObject || document;
  3808. doc.onmouseup = null;
  3809. doc.onmousedown = null;
  3810. doc.oncontextmenu = null;
  3811.  
  3812. var arAllElements = document.getElementsByTagName('*');
  3813. for (var i = arAllElements.length - 1; i >= 0; i--) {
  3814. var elmOne = arAllElements[i];
  3815. elmOne = elmOne.wrappedJSObject || elmOne;
  3816. elmOne.onmouseup = null;
  3817. elmOne.onmousedown = null;
  3818. }
  3819.  
  3820. $(document).unbind("keypress");
  3821. $(document).unbind("keydown");
  3822.  
  3823. // remove body style
  3824. $('link[rel="stylesheet"], script').remove();
  3825. $('body')
  3826. .removeAttr('style')
  3827. .removeAttr('bgcolor');
  3828.  
  3829. $('style').filter(function() {
  3830. var $style = $(this);
  3831. if($style.text().indexOf('#cVim-link-container') != -1) { // chrome 的 cVim 扩展
  3832. return false;
  3833. }
  3834. return true;
  3835. }).remove();
  3836. },
  3837. initDocument: function(parser) {
  3838. document.title = parser.docTitle;
  3839. window.name = "MyNovelReader";
  3840. document.body.innerHTML = $.nano('<div id="container">\n <div id="menu-bar" title="点击显示隐藏章节列表"></div>\n <div id="menu">\n <div id="header" title="打开目录">\n <a href="{indexUrl}" target="_blank">{bookTitle}</a>\n </div>\n <div id="divider"></div>\n <ul id="chapter-list" title="左键滚动,中键打开链接(无阅读模式)">\n </ul>\n </div>\n <div id="mynovelreader-content"></div>\n <div id="loading" style="display:none"></div>\n <div id="preferencesBtn">\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"/>\n </div>\n <div id="alert" style="display: none;">\n <p id="App-notice"></p>\n </div>\n</div>'.uiTrans(), parser);
  3841. },
  3842. clean: function() {
  3843. $('body > *:not("#container, .readerbtn, #reader_preferences, #uil_blocker,iframe[name=\'mynovelreader-iframe\']")').remove();
  3844. $('link[rel="stylesheet"]').remove();
  3845. },
  3846. cleanAgain: function() {
  3847. var host = location.host;
  3848. if (!host.match(/qidian\.com|zongheng\.com/)) { // 只在起点、纵横等网站运行
  3849. return;
  3850. }
  3851.  
  3852. // 再次移除其它不相关的,起点,纵横中文有时候有问题
  3853. setTimeout(App.clean, 2000);
  3854. setTimeout(App.clean, 5000);
  3855. // TM 用 addEventListener('load') 有问题
  3856. window.onload = function() {
  3857. App.clean();
  3858. setTimeout(App.clean, 500);
  3859. };
  3860. },
  3861. toggle: function() {
  3862. if (App.isEnabled) { // 退出
  3863. GM_setValue("auto_enable", false);
  3864. L_setValue("mynoverlreader_disable_once", "true");
  3865.  
  3866. window.location = App.activeUrl;
  3867. } else {
  3868. GM_setValue("auto_enable", true);
  3869. L_removeValue("mynoverlreader_disable_once");
  3870. App.isEnabled = true;
  3871. App.launch();
  3872. }
  3873. },
  3874. removeListener: function() {
  3875. C.log("移除各种事件监听");
  3876. App.remove.forEach(function(_remove) {
  3877. _remove();
  3878. });
  3879. },
  3880. appendPage: function(parser, isFirst) {
  3881. var chapter = $("article:last");
  3882. if (chapter.length && parser.isSection) { // 每次获取的不是一章,而是一节
  3883. var lastText = chapter.find("p:last").remove().text().trim();
  3884. var newPage = parser.content.replace(/<p>\s+/, "<p>" + lastText);
  3885.  
  3886. chapter
  3887. .find(".chapter-footer-nav").remove()
  3888. .end()
  3889. .append(newPage);
  3890.  
  3891. if (!Config.hide_footer_nav) {
  3892. chapter.append($.nano(UI.tpl_footer_nav, parser));
  3893. }
  3894.  
  3895. } else {
  3896. chapter = $("<article>")
  3897. .attr("id", "page-" + App.pageNum)
  3898. .append(
  3899. $("<h1>").addClass("title").text(parser.chapterTitle)
  3900. )
  3901. .append(parser.content)
  3902. .appendTo(App.$content);
  3903.  
  3904. if (!Config.hide_footer_nav) {
  3905. chapter.append($.nano(UI.tpl_footer_nav, parser));
  3906. }
  3907.  
  3908. // App.fixImageFloats(chapter.get(0));
  3909.  
  3910. // 添加到章节列表
  3911. var chapterItem = $("<li>")
  3912. .addClass('chapter')
  3913. .append(
  3914. $("<div>")
  3915. .attr({
  3916. href: "#page-" + App.pageNum,
  3917. "realHref": parser.curPageUrl,
  3918. onclick: "return false;",
  3919. title: parser.chapterTitle
  3920. })
  3921. .text(parser.chapterTitle)
  3922. )
  3923. .prependTo(App.$chapterList);
  3924.  
  3925. if (isFirst) {
  3926. chapterItem.addClass('active');
  3927. }
  3928.  
  3929. App.pageNum += 1;
  3930. App.resetCache();
  3931. }
  3932.  
  3933. App.oArticles.push(chapter[0].outerHTML);
  3934. App.parsers.push(parser);
  3935. },
  3936. resetCache: function() { // 更新缓存变量
  3937. App.menuItems = App.$chapterList.find("div");
  3938. App.scrollItems = $("article");
  3939. },
  3940. registerControls: function() {
  3941. // 内容滚动
  3942. var throttled = _.throttle(App.scroll, 200);
  3943. $(window).scroll(throttled);
  3944.  
  3945. App.registerKeys();
  3946.  
  3947. if (Config.dblclickPause) {
  3948. App.$content.on("dblclick", function() {
  3949. App.pauseHandler();
  3950. });
  3951. }
  3952.  
  3953. // 左侧章节列表
  3954. App.$menuHeader.click(function() {
  3955. App.copyCurTitle();
  3956. });
  3957.  
  3958. App.$menuBar.click(function() {
  3959. UI.hideMenuList();
  3960. });
  3961.  
  3962. App.$doc.on("mousedown", "#chapter-list div", function(event) {
  3963. switch (event.which) {
  3964. case 1:
  3965. var href = $(this).attr("href");
  3966. if (href) {
  3967. App.scrollToArticle($(href));
  3968. } else {
  3969. location.href = $(this).attr("realHref");
  3970. }
  3971. break;
  3972. case 2: // middle click
  3973. L_setValue("mynoverlreader_disable_once", true);
  3974. App.openUrl($(this).attr("realHref"));
  3975. break;
  3976. }
  3977. });
  3978.  
  3979. $("#preferencesBtn").click(function(event) {
  3980. event.preventDefault();
  3981. UI.preferencesShow();
  3982. });
  3983.  
  3984. GM_registerMenuCommand("小说阅读脚本设置".uiTrans(), UI.preferencesShow.bind(UI));
  3985. },
  3986. registerKeys: function() {
  3987. key('enter', function(event) {
  3988. if (UI.$prefs) {
  3989. return;
  3990. }
  3991.  
  3992. App.openUrl(App.indexUrl, "主页链接没有找到".uiTrans());
  3993. App.copyCurTitle();
  3994.  
  3995. event.stopPropagation();
  3996. event.preventDefault();
  3997. });
  3998.  
  3999. key('left', function(event) {
  4000. var scrollTop = $(window).scrollTop();
  4001. if (scrollTop === 0) {
  4002. location.href = App.prevUrl;
  4003. } else {
  4004. var offsetTop = $(App.curFocusElement).offset().top;
  4005. // 在视野窗口内
  4006. if (offsetTop > scrollTop && offsetTop < (scrollTop + $(window).height())) {
  4007. App.scrollToArticle(App.curFocusElement.previousSibling || 0);
  4008. } else {
  4009. App.scrollToArticle(App.curFocusElement);
  4010. }
  4011. }
  4012. return false;
  4013. });
  4014.  
  4015. key('right', function(event) {
  4016. if (App.getRemain() === 0) {
  4017. location.href = App.lastRequestUrl || App.requestUrl;
  4018. } else {
  4019. App.scrollToArticle(App.curFocusElement.nextSibling || App.$doc.height());
  4020. }
  4021.  
  4022. event.preventDefault();
  4023. event.stopPropagation();
  4024. return false;
  4025. });
  4026.  
  4027. key('esc', function(){
  4028. if (UI.$prefs) {
  4029. UI.hide();
  4030. return false;
  4031. }
  4032. });
  4033.  
  4034. key('shift+/', function() {
  4035. UI.openHelp();
  4036. return false;
  4037. });
  4038.  
  4039. key(Config.quietModeKey, function(){
  4040. UI.toggleQuietMode();
  4041. return false;
  4042. });
  4043.  
  4044. key(Config.hideMenuListKey, function(){
  4045. UI.hideMenuList();
  4046. return false;
  4047. });
  4048.  
  4049. key(Config.openPreferencesKey, function(){
  4050. UI.preferencesShow();
  4051. return false;
  4052. });
  4053. },
  4054. copyCurTitle: function() {
  4055. if (Config.copyCurTitle) {
  4056. var title = $(App.curFocusElement).find(".title").text()
  4057. .replace(/第?\S+章/, "").trim();
  4058.  
  4059. GM_setClipboard(title, "text");
  4060. }
  4061. },
  4062. scrollToArticle: function(elem) {
  4063. var offsetTop;
  4064. if (typeof elem == "number") {
  4065. offsetTop = elem;
  4066. } else {
  4067. offsetTop = $(elem).offset().top - parseInt($(elem).css("margin-top"), 10);
  4068. }
  4069.  
  4070. if (Config.scrollAnimate) {
  4071. $("html, body").stop().animate({
  4072. scrollTop: offsetTop
  4073. }, 750, "easeOutExpo");
  4074. } else {
  4075. $("html, body").stop().scrollTop(offsetTop);
  4076. }
  4077. },
  4078. openUrl: function(url, errorMsg) {
  4079. if (url) {
  4080. // ff30 Greasemonkey 会报错:Greasemonkey 访问违规:unsafeWindow 无法调用 GM_openInTab。新建脚本采用按键调用也这样。
  4081. setTimeout(function() {
  4082. GM_openInTab(url, false);
  4083. }, 0);
  4084. } else if (errorMsg) {
  4085. UI.notice(errorMsg);
  4086. }
  4087. },
  4088. pauseHandler: function() {
  4089. App.paused = !App.paused;
  4090. if (App.paused) {
  4091. UI.notice('<b>状态</b>:自动翻页<span style="color:red!important;"><b>暂停</b></span>.'.uiTrans());
  4092. App.$loading.html('自动翻页已经<span style="color:red!important;"><b>暂停</b></span>.'.uiTrans()).show();
  4093. } else {
  4094. UI.notice('<b>状态</b>:自动翻页<span style="color:red!important;"><b>启用</b></span>.'.uiTrans());
  4095. App.scroll();
  4096. }
  4097. },
  4098. scroll: function() {
  4099. if (!App.paused && !App.working && App.getRemain() < Config.remain_height) {
  4100. if (App.tmpDoc) {
  4101. App.loaded(App.tmpDoc);
  4102. } else {
  4103. App.doRequest();
  4104. }
  4105. }
  4106.  
  4107. if (App.isTheEnd) {
  4108. App.$loading.html("已到达最后一页...".uiTrans()).show();
  4109. }
  4110.  
  4111. App.updateCurFocusElement();
  4112. },
  4113. updateCurFocusElement: function() { // 滚动激活章节列表
  4114. // Get container scroll position
  4115. var fromTop = $(window).scrollTop() + $(window).height() / 2;
  4116.  
  4117. // Get id of current scroll item
  4118. var cur = App.scrollItems.map(function() {
  4119. if ($(this).offset().top < fromTop)
  4120. return this;
  4121. });
  4122. // Get the id of the current element
  4123. cur = cur[cur.length - 1];
  4124. var id = cur ? cur.id : "";
  4125.  
  4126. if (App.lastId !== id) {
  4127. App.lastId = id;
  4128.  
  4129. var activeItem = App.menuItems.filter("[href=#" + id + "]"),
  4130. activeTitle = activeItem.text(),
  4131. activeUrl = activeItem.attr("realHref");
  4132.  
  4133. // Set/remove active class
  4134. App.menuItems.parent().removeClass("active");
  4135. activeItem.parent().addClass("active");
  4136.  
  4137. App.curFocusElement = cur;
  4138. App.activeUrl = activeUrl;
  4139.  
  4140. if (Config.addToHistory) {
  4141. var curNum = id.match(/\d+/)[0] - 1; // 当前是第几个
  4142. var curTitle = App.parsers[curNum].docTitle;
  4143. document.title = curTitle;
  4144.  
  4145. // TODO: 起点无法添加整个网址,只能添加后半部分。
  4146. var url = activeUrl.replace('http://read.qidian.com', '');
  4147. try {
  4148. unsafeWindow.history.pushState(null, curTitle, url);
  4149. } catch (e) {
  4150. console.error('添加下一页到历史记录失败', e);
  4151. }
  4152. }
  4153. }
  4154. },
  4155. getRemain: function() {
  4156. var scrollHeight = Math.max(document.documentElement.scrollHeight,
  4157. document.body.scrollHeight);
  4158. var remain = scrollHeight - window.innerHeight - window.scrollY;
  4159. return remain;
  4160. },
  4161. doRequest: function() {
  4162. App.working = true;
  4163. var nextUrl = App.requestUrl;
  4164. App.lastRequestUrl = App.requestUrl;
  4165.  
  4166. if (nextUrl && !App.isTheEnd && !(nextUrl in App.parsedPages)) {
  4167. App.parsedPages[nextUrl] = true;
  4168. App.curPageUrl = App.requestUrl;
  4169. App.requestUrl = null;
  4170.  
  4171. var useiframe = App.site.useiframe;
  4172.  
  4173. App.$loading
  4174. .show()
  4175. .html("")
  4176. .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"))
  4177. .append("<a href='" + nextUrl + "' title='点击打开下一页链接'>正在载入下一页".uiTrans() + (useiframe ? "(iframe)" : "") + "...</a>");
  4178.  
  4179. if (useiframe) {
  4180. App.iframeRequest(nextUrl);
  4181. } else {
  4182. App.httpRequest(nextUrl);
  4183. }
  4184. } else {
  4185. // App.$loading.html("<a href='" + App.curPageUrl + "'>无法使用阅读模式,请手动点击下一页</a>").show();
  4186. }
  4187. },
  4188. httpRequest: function(nextUrl, callback) {
  4189. C.log("获取下一页: " + nextUrl);
  4190. GM_xmlhttpRequest({
  4191. url: nextUrl,
  4192. method: "GET",
  4193. overrideMimeType: "text/html;charset=" + document.characterSet,
  4194. onload: function(res) {
  4195. var doc = parseHTML(res.responseText);
  4196. if (_.isFunction(callback)) {
  4197. callback(doc);
  4198. } else {
  4199. App.beforeLoad(doc);
  4200. }
  4201. }
  4202. });
  4203. },
  4204. iframeRequest: function(nextUrl) {
  4205. C.log("iframeRequest: " + nextUrl);
  4206. if (!App.iframe) {
  4207. var i = document.createElement('iframe');
  4208. App.iframe = i;
  4209. i.name = 'mynovelreader-iframe';
  4210. i.width = '100%';
  4211. i.height = '0';
  4212. i.frameBorder = "0";
  4213. i.style.cssText = '\
  4214. margin:0!important;\
  4215. padding:0!important;\
  4216. visibility:hidden!important;\
  4217. ';
  4218. i.src = nextUrl;
  4219. i.addEventListener('load', App.iframeLoaded, false);
  4220. App.remove.push(function() {
  4221. i.removeEventListener('load', App.iframeLoaded, false);
  4222. });
  4223. document.body.appendChild(i);
  4224. } else {
  4225. App.iframe.contentDocument.location.replace(nextUrl);
  4226. }
  4227. },
  4228. iframeLoaded: function() {
  4229. var iframe = this;
  4230. var body = iframe.contentDocument.body;
  4231.  
  4232. if (body && body.firstChild) {
  4233. doc = iframe.contentDocument;
  4234.  
  4235. var mutationSelector = App.site.mutationSelector;
  4236. if (mutationSelector) {
  4237. App.addMutationObserve(doc, function() {
  4238. App.beforeLoad(doc);
  4239. });
  4240. } else {
  4241. var timeout = App.site.timeout || 0;
  4242.  
  4243. setTimeout(function() {
  4244. App.beforeLoad(doc);
  4245. }, timeout);
  4246. }
  4247. }
  4248. },
  4249. beforeLoad: function(htmlDoc) {
  4250. if (config.PRELOADER) {
  4251. App.tmpDoc = htmlDoc;
  4252. App.working = false;
  4253. App.scroll();
  4254.  
  4255. // 预读图片
  4256. var existSRC = {};
  4257. $(App.tmpDoc).find('img').each(function() {
  4258. var isrc = $(this).attr('src');
  4259. if (!isrc || existSRC[isrc]) {
  4260. return;
  4261. } else {
  4262. existSRC[isrc] = true;
  4263. }
  4264. var img = document.createElement('img');
  4265. img.src = isrc;
  4266. });
  4267. } else {
  4268. App.loaded(htmlDoc);
  4269. }
  4270. },
  4271. loaded: function(doc) {
  4272. var parser = new Parser(App.site, doc, App.curPageUrl);
  4273. parser.getAll(function() {
  4274. App.addNextPage(parser);
  4275. });
  4276. App.tmpDoc = null;
  4277. },
  4278. addNextPage: function(parser) {
  4279. if (parser.content) {
  4280. App.appendPage(parser);
  4281.  
  4282. App.$loading.hide();
  4283. App.requestUrl = parser.nextUrl;
  4284. App.isTheEnd = parser.isTheEnd;
  4285.  
  4286. App.afterLoad();
  4287. } else {
  4288. App.removeListener();
  4289.  
  4290. App.$loading.html(
  4291. '<a href="' + App.curPageUrl + '">错误:没有找到下一页的内容。点击打开下一页链接。</a>'.uiTrans())
  4292. .show();
  4293. }
  4294.  
  4295. App.working = false;
  4296. },
  4297. afterLoad: function() {
  4298. App.tmpDoc = null;
  4299.  
  4300. if (config.PRELOADER) {
  4301. setTimeout(function(){
  4302. App.doRequest();
  4303. }, 200);
  4304. }
  4305. },
  4306. fixImageFloats: function(articleContent) {
  4307. if (!config.fixImageFloats) return;
  4308.  
  4309. articleContent = articleContent || document;
  4310.  
  4311. var imageWidthThreshold = Math.min(articleContent.offsetWidth, 800) * 0.55,
  4312. images = articleContent.querySelectorAll('img:not(.blockImage)');
  4313.  
  4314. for (var i = 0, il = images.length; i < il; i += 1) {
  4315. var image = images[i];
  4316.  
  4317. if (image.offsetWidth > imageWidthThreshold) {
  4318. image.className += " blockImage";
  4319. }
  4320. }
  4321. },
  4322.  
  4323. isSaveing: false,
  4324. saveAsTxt: function() {
  4325. if (App.site.useiframe) {
  4326. alert('暂不支持');
  4327. return;
  4328. }
  4329.  
  4330. if (App.isSaveing) {
  4331. alert('正在保存,请稍后');
  4332. return;
  4333. } else {
  4334. alert('开始一章章获取内容,请耐心等待');
  4335. }
  4336.  
  4337. App.isSaveing = true;
  4338.  
  4339. var chapters = [];
  4340. var fileName;
  4341.  
  4342. var toTxt = function(parser) {
  4343. var html = $.nano('{chapterTitle}\n\n{contentTxt}', parser);
  4344. chapters.push(html);
  4345. };
  4346.  
  4347. var getOnePage = function (parser, nextUrl) {
  4348. if (parser) {
  4349. toTxt(parser);
  4350. nextUrl = parser.nextUrl;
  4351. }
  4352.  
  4353. if (!nextUrl) {
  4354. console.log('全部获取完毕');
  4355. saveAs(chapters.join('\n\n'), fileName);
  4356. App.isSaveing = false;
  4357. return;
  4358. }
  4359.  
  4360. if (App.site.useiframe) {
  4361. // App.iframeRequest(nextUrl);
  4362. } else {
  4363. console.log('[存为txt]正在获取:', nextUrl)
  4364. App.httpRequest(nextUrl, function(doc) {
  4365. var par = new Parser(App.site, doc, nextUrl);
  4366. par.getAll(getOnePage)
  4367. });
  4368. }
  4369. };
  4370.  
  4371. App.parsers.forEach(toTxt);
  4372. // 保存后面的章节
  4373. var lastParser = App.parsers[App.parsers.length - 1];
  4374. fileName = lastParser.bookTitle + '.txt';
  4375. getOnePage(null, lastParser.nextUrl);
  4376. }
  4377. };
  4378.  
  4379. var BookLinkMe = {
  4380. clickedColor: "666666",
  4381.  
  4382. init: function() {
  4383. if (location.host != 'booklink.me') return;
  4384.  
  4385. this.addUnreadButton();
  4386.  
  4387. if (location.pathname.indexOf("/book-") === 0) {
  4388. this.chapterPageAddTiebaLink();
  4389. }
  4390. },
  4391. addUnreadButton: function(){ // 添加一键打开所有未读链接
  4392. var $parent = $('td[colspan="2"]:contains("未读"):first, td[colspan="2"]:contains("未讀"):first');
  4393. if(!$parent.length) return;
  4394.  
  4395. var openAllUnreadLinks = function(event){
  4396. event.preventDefault();
  4397.  
  4398. var links = $x('./ancestor::table[@width="100%"]/descendant::a[img[@alt="未读"]]', event.target);
  4399. links.forEach(function(link){
  4400. // 忽略没有盗版的
  4401. var chapterLink = link.parentNode.nextSibling.nextSibling.querySelector('a');
  4402. if (chapterLink.querySelector('font[color="800000"]')) {
  4403. return;
  4404. }
  4405.  
  4406. if(isFirefox)
  4407. link.click();
  4408. else
  4409. GM_openInTab(link.href);
  4410.  
  4411. // 设置点击后的样式
  4412. // 未读左边的 1x 链接
  4413. link.parentNode.previousSibling.querySelector('font')
  4414. .setAttribute('color', BookLinkMe.clickedColor);
  4415. chapterLink.classList.add('mclicked');
  4416. });
  4417. };
  4418.  
  4419.  
  4420. $('<a>')
  4421. .attr({ href: 'javascript:;', title: '一键打开所有未读链接', style: 'width:auto;' })
  4422. .click(openAllUnreadLinks)
  4423. .append($('<img src="me.png" style="max-width: 20px;">'))
  4424. .appendTo($parent);
  4425. },
  4426. chapterPageAddTiebaLink: function() {
  4427. var link = $('font:contains("贴吧")').parent().get(0);
  4428. if (!link) return;
  4429.  
  4430. var tiebaUrl = 'http://tieba.baidu.com/f?kw=' + $('h1').text();
  4431. console.log('GM_xmlhttpRequest', tiebaUrl);
  4432. GM_xmlhttpRequest({
  4433. method: "GET",
  4434. url: tiebaUrl,
  4435. onload: function(response) {
  4436. var doc = parseHTML(response.responseText);
  4437. BookLinkMe.load(doc);
  4438. }
  4439. });
  4440. },
  4441. load: function(doc) {
  4442. var $data = $(doc).find('.threadlist_text > a').map(function() {
  4443. return {
  4444. title: $(this).text(),
  4445. url: 'http://tieba.baidu.com' + $(this).attr('href')
  4446. }
  4447. });
  4448.  
  4449. var trimTitle = function(title, strict) {
  4450. title = title.trim()
  4451. .replace(/\.\.\.$/, '');
  4452.  
  4453. if (strict) {
  4454. title = title.replace(/第.*?章\s*/, '');
  4455. }
  4456.  
  4457. // if (toNum) {
  4458. // title = title.replace(/[零一二三四五六七八九十百千万亿]+/, cnNum2ArabNum);
  4459. // }
  4460.  
  4461. return title;
  4462. };
  4463.  
  4464. var findUrl = function(sTitle) {
  4465. if (!sTitle) return;
  4466.  
  4467. var url;
  4468. $data.each(function(i, item) {
  4469. var tiebaTitle = item.title;
  4470. if (tiebaTitle.indexOf(trimTitle(sTitle)) > 0 ||
  4471. sTitle.indexOf(trimTitle(tiebaTitle, true)) > 0 // 包含贴吧标题的部分
  4472. ) {
  4473. url = item.url;
  4474. return true;
  4475. }
  4476. });
  4477.  
  4478. return url;
  4479. };
  4480.  
  4481. $('a:contains("搜索本章节")').each(function(){
  4482. var $this = $(this),
  4483. $thisLine = $this.parent().parent(),
  4484. chapterTitle = $thisLine.prev().find('a[href^="/jump.php"]:first').text();
  4485.  
  4486. var url = findUrl(chapterTitle);
  4487. if (url) {
  4488. $('<a>')
  4489. .attr({ target: '_blank', href: url })
  4490. .text('贴吧')
  4491. .appendTo($this.parent());
  4492. }
  4493. });
  4494. }
  4495. };
  4496.  
  4497. if (location.host === 'booklink.me') {
  4498. BookLinkMe.init();
  4499. } else {
  4500. App.init();
  4501. }