clumsyman / zhaishuyuan

// ==UserScript==
// @name         zhaishuyuan
// @namespace    http://tampermonkey.net/
// @version      0.3
// @description  load multile chapters
// @author       clumsyman
// @copyright 2018, clumsyman (https://openuserjs.org//users/clumsyman)
// @license MIT
// @match        https://www.shuchong.info/chapter/*
// @match        https://www.shuchong.info/user/bookcase/*
// @match        https://mp.weixin.qq.com/s/*
// @match        https://sj.uukanshu.com/read.aspx
// @match        https://m.readbook8.com/user/bookcase.php
// @match        https://m.readbook8.com/*/*_*.html
// @match        https://m.dushu8.com/user/bookcase.php
// @match        https://m.dushu8.com/*/*.html
// @exclude      /https?:\/\/m\.dushu8\.com\/.*/index_.*\.html/
// @grant        none
// ==/UserScript==

javascript:(function () {
try {
	function toRE(s) {
		var i = s.indexOf('=');
		return [new RegExp(i < 0 ? s : s.substring(0, i)), i < 0 ? '' : s.substring(i + 1)];
	}
	function parseReplacements(query, fn) {
		return query.split('&')
			.filter(s => s.length > 0)
			.map(fn);
	}
	var replacements = parseReplacements('[?\?]=\u2047', toRE);
	function toggleReplacementWrapper() {
		this.classList.toggle('replaced');
	}
	function createReplacementInner(className, text) {
		var span = document.createElement('span');
		span.className = className;
		span.textContent = text;
		return span;
	}
	function createReplacementWrapper(original, replacer) {
		var span = document.createElement('span');
		span.className = 'replacement replaced';
		span.appendChild(createReplacementInner('original', original));
		span.appendChild(createReplacementInner('replacer', replacer));
		span.addEventListener('click', toggleReplacementWrapper);
		return span;
	}
	function createReplacementStyles() {
		var style = document.body.querySelector('style#zhaishuyuan');
		if (!style) {
			style = document.body.appendChild(document.createElement('style'));
			style.id = 'zhaishuyuan';
			style.append(document.createTextNode([
				'.replacement { border: #0099ff solid 1px; }',
				'.replacer { color: #ff6600; }',
				'.replacement.replaced .original { display: none; }',
				'.replacement:not(.replaced) .replacer { display: none; }',
				'.chapter_box { word-wrap: break-word; }',
				'.chapter_title {',
				'  background: #ecfcfc;',
				'  border: solid 1px #e8e8e8;',
				'  color: #8dadad;',
				'  text-align: center;',
				'}'
			].join('\n')));
			return style;
		} else {
			alert('found embedded <style>');
			return null;
		}
	}
	function getBody(content) {
		var x = content.indexOf('<body');
		x = content.indexOf('>', x);
		var y = content.lastIndexOf('</body>');
		return content.slice(x + 1, y);
	}
	function shuchong() {
		var pathname = window.location.pathname;
		if (pathname.startsWith('/user/bookcase/'))
			shuchong_bookcase();
		else if (pathname.startsWith('/chapter/'))
			shuchong_chapter();
		else
			alert(pathname);
	}
	function shuchong_bookcase() {
		var links = document.querySelectorAll('.booklist a[data-url][onclick]');
		for (var i = 0; i < links.length; i++) {
			var link = links[i];
			link.href = link.getAttribute('data-url');
			link.removeAttribute('data-url');
			link.removeAttribute('onclick');
			link.setAttribute('target', '_blank');
		}
	}
	function shuchong_chapter() {
		var global_find = $;
		var prev_store = document.getElementById('prev_store');
		if (!prev_store) {
			prev_store = document.createElement('div');
			prev_store.id = 'prev_store';
			prev_store.style.display = 'none';
			document.body.appendChild(prev_store);
		}
		function findPrev(a, b) {
			return global_find(a, '#prev_store');
		}
		function loadPrev(body) {
			prev_store.innerHTML = body;
			var scripts = prev_store.querySelectorAll('#center script:not([src])');
			for (var i = 0; i < scripts.length; i++)
				eval(scripts[i].innerText);
			return prev_store;
		}
		function updatePrevChapterLinks(prev_url) {
			for (var i = 0; i < nr_pages.length; i++) {
				nr_pages[i].firstElementChild.href = prev_url;
			}
		}
		function getPrevUrl(container) {
			return container.querySelector('.chapter-page').firstElementChild.href;
		}
		function invokeDecode(container) {
			var scripts = container.querySelectorAll('script:not([src])');
			for (var i = 0; i < scripts.length; i++) {
				var idx = scripts[i].innerText.indexOf('function getDecode(){');
				if (idx >= 0) {
					eval(scripts[i].innerText.substring(idx));
					getDecode();
				}
			}
		}
		function findContent(container) {
			invokeDecode(container);
			var content = container.querySelector('.chapter-name').nextElementSibling.nextElementSibling;
			var a_c = content.querySelectorAll('a.c_red');
			for (var i = 0; i < a_c.length; i++)
				a_c[i].parentElement.removeChild(a_c[i]);
			a_c = content.querySelectorAll('a.c_green');
			for (var i = 0; i < a_c.length; i++)
				a_c[i].parentElement.removeChild(a_c[i]);
			return content;
		}
		function findTitle(container) {
			var title = document.createElement('p');
			title.className = 'chapter_title';
			var nodes = container.querySelector('.chapter-name').childNodes;
			for(var i = 0; i < nodes.length; i++)
				title.appendChild(nodes[i]);
			return title;
		}
		function loadPrevChapter() {
			try {
				var xhr = new XMLHttpRequest();
				xhr.open('GET', getPrevUrl(document.body), false);
				xhr.overrideMimeType('text\/plain; charset=gb2312');
				xhr.send();
				if (xhr.readyState == 4 && xhr.status == 200) {
					var body = getBody(xhr.responseText);
					$ = findPrev;
					loadPrev(body);
					var prev_content = findContent(prev_store);
					$ = global_find;
					for (var last; last = prev_content.lastElementChild; )
						wap_content.insertBefore(last, wap_content.firstElementChild);
					var prev_title = findTitle(prev_store);
					wap_content.insertBefore(prev_title, wap_content.firstElementChild);
					updatePrevChapterLinks(getPrevUrl(prev_store));
				} else {
					alert('readyState='+xhr.readyState+', status='+xhr.status+', statusText='+xhr.statusText);
				}
			} catch(e) {
				alert(e + '\n' + e.stack);
			} finally {
				return false;
			}
		}
		if (document.styleSheets.length > 0)
			document.styleSheets[0].disabled = true;
		var style = createReplacementStyles();
		style.append(document.createTextNode('html { -webkit-touch-callout:default; -webkit-user-select:text; }\n'));
		style.append(document.createTextNode('#loading, .show, .flt_setting, .copyright, .subhead, .book_clist, .layout-con { display: none; }\n'));
		style.append(document.createTextNode('.search-btn {\n'
			+'	width: 22px;\n'
			+'	height: 22px;\n'
			+'	background: url(https:\/\/img.zhaishuyuan.com/zhai/img/sprites.png) -7px -77px no-repeat #49A9A9;\n'
			+'	border: 0;\n'
			+'	text-indent: -9999px;\n'
			+'}\n'));
		var wap_content = findContent(document.body);
		wap_content.insertBefore(findTitle(document.body), wap_content.firstElementChild);
		var nr_pages = document.querySelectorAll('.chapter-page');
		for (var i = 0; i < nr_pages.length; i++) {
			var nr_page = nr_pages[i];
			nr_page.firstElementChild.onclick = loadPrevChapter;
		}
		var search = document.querySelector('#search>.search-text');
		if (search)
			search.removeAttribute('placeholder');					
		$(window).off('scroll');
		var expires = new Date();
		expires.setFullYear(expires.getFullYear()+10);
		document.cookie = 'buy=1;expires='+expires.toGMTString()+';path=/;';
	}
	function uukanshu() {
		var RE_uukanshu = /[uUuU][uUuU]看书[  ]?[wWwW][wWwW][wWwW][..][uUuU][uUuU][kKkK][aAaA][nNnN][sSsS][hHhH][uUuU][..][cCcC][oOoO][mMmM]/g;
		var prev_store = document.getElementById('prev_store');
		if (!prev_store) {
			prev_store = document.createElement('div');
			prev_store.id = 'prev_store';
			prev_store.style.display = 'none';
			document.body.appendChild(prev_store);
		}
		function findContent(container) {
			var content = container.querySelector('#bookContent');
			content.innerHTML = content.innerHTML.replace(RE_uukanshu, '');
			var boxes = content.querySelectorAll('.box');
			for (var i = 0; i < boxes.length; i++)
				boxes[i].parentElement.removeChild(boxes[i]);
			return content;
		}
		function findTitle(container) {
			var title = container.querySelector('h3');
			return title;
		}
		function getPrevUrl(container) {
			return container.querySelector('.rp-switch #read_pre').href;
		}
		function loadPrev(body) {
			prev_store.innerHTML = body;
			return prev_store;
		}
		function updatePrevChapterLinks(prev_url) {
			document.body.querySelector('.rp-switch #read_pre').href = prev_url;
		}
		function loadPrevChapter(event) {
			try {
				var xhr = new XMLHttpRequest();
				xhr.open('GET', getPrevUrl(document.body), false);
				xhr.overrideMimeType('text/html; charset=utf-8');
				xhr.send();
				if (xhr.readyState == 4 && xhr.status == 200) {
					var body = getBody(xhr.responseText);
					loadPrev(body);
					var prev_content = findContent(prev_store);
					for (var last; last = prev_content.lastChild; )
						wap_content.insertBefore(last, wap_content.firstChild);
					var prev_title = findTitle(prev_store);
					wap_content.insertBefore(prev_title, wap_content.firstChild);
					updatePrevChapterLinks(getPrevUrl(prev_store));
				} else {
					alert('readyState='+xhr.readyState+', status='+xhr.status+', statusText='+xhr.statusText);
				}
			} catch(err) {
				alert(err + '\n' + err.stack);
			} finally {
				event.stopPropagation();
				return false;
			}
		}
		var style = createReplacementStyles();
		if (style) {
			style.append(document.createTextNode([
				'.samebooks1, .share { display: none; }',
				'#read-page .rp-switch { padding: 0; }'
			].join('\n')));

			var wap_content = findContent(document.body);
			wap_content.insertBefore(findTitle(document.body), wap_content.firstChild);

			var navs = document.querySelectorAll('.rp-switch');
			if (navs.length == 1) {
				var nav_foot = navs[0];
				var nav_head = nav_foot.cloneNode(true);
				var nav_next = nav_head.querySelector('a:last-child');
				if (nav_next)
					nav_head.removeChild(nav_next);
				var nav_prev = nav_foot.querySelector('#read_pre');
				if (nav_prev)
					nav_foot.removeChild(nav_foot.querySelector('#read_pre'));
				wap_content.parentNode.insertBefore(nav_head, wap_content);
				nav_prev = nav_head.querySelector('#read_pre');
				nav_prev.ontouchend = loadPrevChapter;
				nav_next = nav_foot.querySelector('#read_next');
			}
		}
	}
	function weixin() {
		createReplacementStyles();
		document.getElementById('meta_content').style.display = 'none';
	}
	function readbook8() {
		var pathname = window.location.pathname;
		if (pathname == '/user/bookcase.php')
			readbook8_bookcase();
		else if (/\/\w+\/\d+(_\d)?\.html/.test(pathname))
			readbook8_chapter();
		else
			alert(pathname);
	}
	function createStore(id) {
		var store = document.getElementById(id);
		if (!store) {
			store = document.createElement('div');
			store.id = id;
			store.style.display = 'none';
			document.body.appendChild(store);
		}
		return store;
	}
	function readbook8_bookcase() {
	}
	function readbook8_chapter() {
		var load_store = createStore('load_store');
		function findContent(container) {
			return container.querySelector('#chaptercontent');
		}
		function findNextLinks(container) {
			return container.querySelectorAll('a#pb_next');
		}
		function findPrevLinks(container) {
			return container.querySelectorAll('a#pb_prev');
		}
		function queryContent(url) {
			try {
				var xhr = new XMLHttpRequest();
				xhr.open('GET', url, false);
				xhr.overrideMimeType('text\/plain; charset=gb2312');
				xhr.send();
				if (xhr.readyState == 4 && xhr.status == 200) {
					load_store.innerHTML = getBody(xhr.responseText);
					var content = findContent(load_store);
					trimContentFooter(content);
					trimContentHeader(content);
					var nextUrl = findNextLinks(load_store)[0].href;
					var prevUrl = findPrevLinks(load_store)[0].href;
					return [content.innerHTML, nextUrl, prevUrl];
				} else {
					alert('readyState='+xhr.readyState+', status='+xhr.status+', statusText='+xhr.statusText);
				}
			} catch(e) {
				alert(e + '\n' + e.stack);
			}
		}
		var RE_pagination = /^(.*)\(第(\d+)\/\d+页\)$/;
		function trimContentHeader(content) {
			if (content.firstChild.nodeName == '#text') {
				var match = RE_pagination.exec(content.firstChild.nodeValue);
				if (!match) {
					alert('unexpected header: '+content.firstChild.nodeValue);
				} else if (match[2] == 1) {
					content.firstChild.nodeValue = match[1];
					var node = content.firstChild.nextSibling;
					while(node && (node.nodeName == 'BR' || node.nodeName == '#text' && /^\s*$/.test(node.nodeValue)))
						node = node.nextSibling;
					if (node && node.nodeName == '#text' && /^\s*您可以在百度里搜索“.*”查找最新章节!\s*$/.test(node.nodeValue)) {
						var next = node.nextSibling;
						node.remove();
						node = next;
						while(node && (node.nodeName == 'BR' || node.nodeName == '#text' && /^\s*$/.test(node.nodeValue))) {
							next = node.nextSibling;
							node.remove();
							node = next;
						}
					}
				} else {
					content.removeChild(content.firstChild);
					while(content.firstChild.nodeName == 'BR') {
						content.removeChild(content.firstChild);
					}
				}
			}
		}
		function trimContentFooter(content) {
			if (content.lastChild.nodeName == '#text' && 
			    /^  读书吧中文网阅读网址:[a-z0-9.]*$/.test(content.lastChild.nodeValue)) {
				content.removeChild(content.lastChild);
			}
			while(content.lastChild.nodeName == 'BR') {
				content.removeChild(content.lastChild);
			}
		}
		function loadPrevChapter(event) {
			try {
				var prevLinks = findPrevLinks(document.body);
				var page = queryContent(prevLinks[0].href);
				if (page) {
					var joined = page[0];
					var nextUrl = page[1];
					var prevUrl = page[2];
					while(/\/\d+_\d+\.html/.test(nextUrl)) {
						page = queryContent(nextUrl);
						if (page) {
							joined += page[0];
							nextUrl = page[1];
						}
					}
					content.innerHTML = joined + '<br><br>' + content.innerHTML;
					for(var i = prevLinks.length; i-- > 0;) {
						prevLinks[i].href = prevUrl;
					}
				}
			} catch(err) {
				alert(err + '\n' + err.stack);
			} finally {
				event.stopPropagation();
				return false;
			}
		}
		var style = document.body.querySelector('style#clumsyman');
		if (style) {
			alert('found embedded <style>');
			/*return;*/
		} else {
			style = document.body.appendChild(document.createElement('style'));
			style.id = 'clumsyman';
			style.append(document.createTextNode([
				'#g, #g + div, .layui-row, .addbook { display: none; }',
			].join('\n')));
		}
		var content = findContent(document.body);
		if (content) {
			trimContentHeader(content);
			trimContentFooter(content);
		}
		var prevLinks = findPrevLinks(document.body);
		if (prevLinks.length) {
			for(var i = prevLinks.length; i-- > 0;) {
				prevLinks[i].onclick = loadPrevChapter;
			}
		}
		var addBook = document.body.querySelector('div.addbook');
		if (addBook) {
			var addBookMark = addBook.firstElementChild;
			if (addBookMark) {
				for(var i = prevLinks.length; i-- > 0;) {
					prevLinks[i].parentElement.appendChild(addBookMark.cloneNode(true));
				}
			}
		}
		var nextLinks = findNextLinks(document.body);
		if (nextLinks.length) {
			var joined = content.innerHTML;
			var nextUrl = nextLinks[0].href;
			while(/\/\d+_\d+\.html/.test(nextUrl)) {
				var page = queryContent(nextUrl);
				if (page) {
					joined += page[0];
					nextUrl = page[1];
				}
			}
			for(var i = nextLinks.length; i-- > 0;) {
				nextLinks[i].href = nextUrl;
			}
			content.innerHTML = joined;
		}
	}
	function twokzw() {
		var pathname = window.location.pathname;
		if (/\/\d+\/\d+\/\d+(_\d)?\.html/.test(pathname))
			twokzw_chapter();
		else
			alert(pathname);
	}
	function twokzw_chapter() {
		var load_store = createStore('load_store');
		function findContent(container) {
			return container.querySelector('#nr1');
		}
		function findNextLinks(container) {
			return container.querySelectorAll('a#pb_next');
		}
		function findPrevLinks(container) {
			return container.querySelectorAll('a#pb_prev');
		}
		function queryContent(url) {
			try {
				var xhr = new XMLHttpRequest();
				xhr.open('GET', url, false);
				xhr.overrideMimeType('text\/html; charset=utf-8');
				xhr.send();
				if (xhr.readyState == 4 && xhr.status == 200) {
					load_store.innerHTML = getBody(xhr.responseText);
					var content = findContent(load_store);
					trimTitle(content);
					var nextUrl = findNextLinks(load_store)[0].href;
					var prevUrl = findPrevLinks(load_store)[0].href;
					return [content.innerHTML, nextUrl, prevUrl];
				} else {
					alert('readyState='+xhr.readyState+', status='+xhr.status+', statusText='+xhr.statusText);
				}
			} catch(e) {
				alert(e + '\n' + e.stack);
			} finally {
				load_store.innerHTML = '';
			}
		}
		function completeChapter(chapter) {
			while(/\/\d+_\d+\.html/.test(chapter[1])) {
				var sequent = queryContent(chapter[1]);
				if (sequent) {
					var matchE = /\S(<\/p>\s*)$/.exec(chapter[0]);
					var matchS = /^(\s*<p>)\S/.exec(sequent[0]);
					if (matchE && matchS) {
						chapter[0] = chapter[0].slice(0, -matchE[1].length);
						sequent[0] = sequent[0].substring(matchS[1].length);
					}
					chapter[0] += sequent[0];
					chapter[1] = sequent[1];
				}
			}
		}
		function loadPrevChapter(event) {
			try {
				var prevLinks = findPrevLinks(document.body);
				var chapter = queryContent(prevLinks[0].href);
				if (chapter) {
					completeChapter(chapter);
					content.innerHTML = chapter[0] + content.innerHTML;
					for(var i = prevLinks.length; i-- > 0;) {
						prevLinks[i].href = chapter[2];
					}
				}
			} catch(err) {
				alert(err + '\n' + err.stack);
			} finally {
				event.stopPropagation();
				return false;
			}
		}
		var RE_pagination = /^[-\s]*(.*[^-\s])[-\s]*((\d+)\s*\/\s*\d+)\s*$/;
		function trimTitle(content) {
			var title = content.parentElement.parentElement.querySelector("H1");
			if (title) {
				var match = RE_pagination.exec(title.innerText);
				if (!match) {
					alert('unexpected title: '+title);
				} else if (match[2] == 1) {
					title.innerText = match[1];
					content.insertBefore(title, content.firstChild);
				}
			}
			return title;
		}

		var style = document.body.querySelector('style#clumsyman');
		if (style) {
			alert('found embedded <style>');
			return;
		} else {
			style = document.body.appendChild(document.createElement('style'));
			style.id = 'clumsyman';
			style.append(document.createTextNode([
				'#nr_title { font-size: 20px; font-weight: bold; }'
			].join('\n')));
		}
		var content = findContent(document.body);
		if (content) {
			document.title = trimTitle(content).innerHTML;
		}
		
		var nextLinks = findNextLinks(document.body);
		if (nextLinks.length) {
			var tdNext = nextLinks[0].parentElement;
			var tdMulu = tdNext.previousElementSibling;
			if (tdMulu.className = 'mulu') {
				tdMulu.querySelector('a').text = '返回目录';
				var bookmark = document.body.querySelector('#shuqian');
				if (bookmark) {
					tdMulu.parentElement.insertBefore(shuqian.parentElement, tdMulu);
				}
			}
			var table = tdNext;
			while(table.tagName != 'TABLE') table = table.parentElement;
			var nr_page = table.parentElement;
			while(table.previousElementSibling)
				nr_page.removeChild(table.previousElementSibling);
			while(table.nextElementSibling)
				nr_page.removeChild(table.nextElementSibling);
			nr_page.innerHTML;
			document.body.querySelector('.nr_page').innerHTML = nr_page.innerHTML;

			nextLinks = findNextLinks(document.body);
			var chapter = [content.innerHTML, nextLinks[0].href];
			completeChapter(chapter);
			content.innerHTML = chapter[0];
			for(var i = nextLinks.length; i-- > 0;) {
				nextLinks[i].text = '下一章';
				nextLinks[i].href = chapter[1];
			}
		}
		var prevLinks = findPrevLinks(document.body);
		if (prevLinks.length) {
			for(var i = prevLinks.length; i-- > 0;) {
				prevLinks[i].onclick = loadPrevChapter;
			}
		}
	}
	function mismatch() {
		alert(window.location.hostname);
	}
	var handlers = {
		'www.shuchong.info': shuchong,
		'mp.weixin.qq.com': weixin,
		'sj.uukanshu.com': uukanshu,
		'm.readbook8.com': readbook8,
		'm.dushu8.com': readbook8,
		'm.2kzw.cc': twokzw,
	};
	(handlers[window.location.hostname] || mismatch)();
} catch(e) {
	alert(e + '\n' + e.stack);
}
})();