Улучшеный просмотрщик для acomics.ru / Enhanced viewer for acomics.ru

Предзагрузка, удобная навигация и прочие улучшения для сайта acomics.ru

当前为 2015-06-19 提交的版本,查看 最新版本

// ==UserScript==
// @name            Улучшеный просмотрщик для acomics.ru / Enhanced viewer for acomics.ru
// @description     Предзагрузка, удобная навигация и прочие улучшения для сайта acomics.ru
// @author          Sanya_Zol (Alexander Zolotarev)
// @license         Public domain
// @icon            https://acomics.ru/favicon.ico
// @homepageURL     https://gf.qytechs.cn/ru/users/365-sanya-zol
// @namespace       Sanya_Zol
// @version         0.1.0-rc.1+inject
// @include         http://acomics.ru/*
// @include         https://acomics.ru/*
// @run-at          document-end
// @grant           none
// ==/UserScript==

/*
################################################################################
#########################       вместо README.md       #########################
################################################################################

Описание
====================
Улучшеный просмотрщик комиксов для сайта [http://acomics.ru/](acomics.ru)

* **Быстрый переход** между страницами нажатием стрелок [˂], [˃]
* **Скриптовая прокрутка** стрелками [˄], [˅]
    *(Мне вот очень удобно читать комикс и комментарии одной рукой)*
* Автоматическое **сохранение номера страницы** для каждого комикса (в localStorage).
* **Предзагрузка** страниц - моментальный переход между страницами!
* **Отключение уменьшения изображения**
    Некоторые комиксы, например [этот](http://acomics.ru/~unsounded/1), автоматически уменьшаются, что не есть хорошо. В частности, [тема поднималась в этом обсуждении](http://acomics.ru/forum/index.php?showtopic=2441&st=345&p=242192#entry242192):
    *> Можно увеличить max-width под комикс? Unsounded со своими 1024 все еще масштабируется в минус.*

Как пользоваться
====================
Если вы этого ещё не сделали, [устанавливаем расширение Greasemonkey (или его аналог) для своего браузера](https://gf.qytechs.cn/ru/help/installing-user-scripts)

Заходим на страницу скрипта и жмем "Установить этот скрипт". Должно вылезти предложение установить скрипт - если его не будет, значит вы неправильно установили Greasemonkey (или его аналог).

После установки скрипта заходим на страницу комикса (например, [http://acomics.ru/~unsounded/1](http://acomics.ru/~unsounded/1) ) и жмем появившуюся кнопку в правом верхнем углу.

В случае, если вы в прошлый закончили чтение на другой странице комикса - произойдет переход на неё и надо будет ещё раз нажать кнопку.

Управление
--------------------
[˂], [˃] {cтрелки влево и вправо} - переход по страницам
[˄], [˅] {cтрелки вверх и вниз} - прокрутка вверх-вниз
Shift+[˄] или Shift+[˅] - переключение режима прокрутки вверх-вниз (браузер / скрипт, по умолчанию "скрипт")
Ctrl+[˄] или Ctrl+[˅] - плавная прокрутка (при режиме прокрутки "скрипт")

Рекомендую увеличить масштаб при чтении комикса ( крутите колесо мыши вверх, зажав клавишу Ctrl )

Номер страницы автоматически сохраняется.

Если вдруг вам надо поменять номер страницы - это можно сделать довольно несложным способом (не знаю куда кнопку прицепить):
1. Запускаем читалку нажатием кнопки. **Читалка должна быть запущена, чтобы это работало.**
2. Открываем "Инструменты разработчика" (Developer's Tools), это можно сделать, нажав `Ctrl+Shift+I` **или** кликнув на странице правой кнопкой и выбрав "Проинспектировать элемент" (Inspect Element).
3. Идем на вкладку "Консоль" (Console).
4. *На вкладке консоли в зависимости от браузера вас может встретить предупреждение, блокирующее вставку или консоль.*
5. Вводим (или вставляем) туда `z_SetPage();` и жмем Enter.
6. Вводим в поле новый номер страницы.

Прочее
====================
Есть ещё некоторые недокументированные функции и настройки, но мне лень их документировать. Если интересно, смотрите код.

Authors
--------------------
* Sanya_Zol (Alexander Zolotarev)

Contributing
--------------------
Contributions must be under the same licence.
mailto: sanya.zol%gmail

License
--------------------
*Public domain*

I, the copyright holder of this work, release this work into the public domain. This applies worldwide.
In some countries this may not be legally possible; if so:
I grant anyone the right to use this work for any purpose, without any conditions, unless such conditions are required by law.

################################################################################
#########################        конец README.md       #########################
################################################################################
*/


(function(){

// http://stackoverflow.com/questions/805107/creating-multiline-strings-in-javascript
var hereDoc=function(f){return f.toString().replace(/^[^\/]+\/\*!?/,'').replace(/\*\/[^\/]+$/,'');};
var a = hereDoc(function() {/*!

// чтобы поменять номер страницы, открой консоль (Ctrl+Shift+I, вкладка "Console") и введи там
// z_SetPage()

var PAGE = {}; // не трогать. так надо.

PAGE.AjaxRequestTimeoutMs=10000;
// таймаут запроса в милисекундах (секундах*1000)

// чтобы деактивировать или снова активировать быстрый скролл, нажми Shift+[˄] или Shift+[˅]
PAGE.scrollFasterDefault = true;
// по умолчанию он включен, чтобы отключить поменяй на false

PAGE.scrollFasterPx = 300;
PAGE.scrollFasterCtrlPx = 100;
// сейчас при скролле страницы стрелками по вертикали [˄] и [˅] будет быстрый скролл на 300 пикселей
// а при зажатом Ctrl - на 100
// поменяй на нужное количество пикселей
PAGE.scrollFasterSpeed = 75;
// время в милисекундах, за которое скроллить при использовании быстрого скролла
PAGE.scrollSpeed = 75;
// время в милисекундах, за которое скроллить наверх при смене страниц

PAGE.contentMarginMover = false;
// поставь true чтобы выпилить комментарии - они будут вылазить при нажатии [˄]+[˃]
// (стрелки вправо при зажатой стрелке вверх) и выезжать при нажатии [˂]+[˃]
// мне это показалось не очень удобным и я вернул как было

PAGE.visualLog = false;
// поставь true чтобы выводить отладочную информацию в левом верхнем углу страницы
// отладочная страница в консоли (Ctrl+Shift+I, вкладка "Console")

PAGE.localStorageKeyPrefix = '**zol**page**';
// префикс хранилища html5 (которое localStorage и sessionStorage)

PAGE.init = function(){
	
	// var m = /^\/~([^/]+)\/(.*)$/.exec( location.pathname.toString() );
	var m = /^\/~([^\/]+)\/(\d*)(?:\D|$)/.exec( location.pathname.toString() );
	if(!m){return;}
	
	// parse page info
	PAGE.comicsName = m[1];
	var comicsPage = parseInt(m[2]);
	if( m[2]=='' || isNaN(comicsPage) || comicsPage<1 ) {
		return;
	}
	PAGE.comicsPage = comicsPage;
	delete m;
	delete comicsPage;
	
	// if( PAGE.contentMarginMover ){ PAGE.$contentMargin }
	
	PAGE.init = function(){};
	PAGE.makeUrl = function(id){
		return '/~'+PAGE.comicsName+'/'+id;
	};
	

	if( PAGE.visualLog ){
		(function(){
			var d = $('<div/>');
			d.css({
				position:'fixed', // absolute
				zIndex:1e6,
				left:'1px',
				top:'1px',
				padding:'1px',
				fontFamily:'Verdana',
				fontSize:'7px',
				color:'#fff',
				textShadow:'#000 0px 0px 1px',//, #000 2px 2px 2px
				background:'rgba(255,255,255,0.3)',
				borderRadius:'2px',
				border:'1px rgba(255,255,255,0.5) solid',
				overflowY:'hidden',
				maxHeight:'60px'
			}).appendTo('body');
			PAGE.log = function(s){
				$('<div/>').text(s).hide().prependTo(d).slideDown(200).delay(5000).slideUp(200,function(){ $(this).remove(); });
				d.fadeIn().finish().delay(5000).slideUp(200);
				console.log('[PAGE] '+s);
			};
		})();
	} else {
		PAGE.log = function(s){
			console.log('[PAGE] '+s);
		};
	}
	
	PAGE.changeHandlers = function(){
		PAGE.store();
		PAGE.ShouldIDoSomething();
		// history.pushState({}, , location.href);
		history.pushState({page:PAGE.comicsPage}, '#'+PAGE.comicsPage+' | '+PAGE.comicsPageTitle, PAGE.makeUrl(PAGE.comicsPage));
	};
	$(window).on('popstate', function(e){
		var d = e.originalEvent.state || false;
		if(d && d.page){
			PAGE.wantPage = d.page;
			PAGE.ShouldIDoSomething();
		}
	});
	
	var $htmlbody = $('html,body');
	PAGE.scroll = function( relative, scrollAmount ){
		if(relative){
			$htmlbody.finish().animate({
				scrollTop: Math.max( 0, $(window).scrollTop() + scrollAmount )
			}, PAGE.scrollFasterSpeed);
		} else {
			$htmlbody.finish().animate({
				scrollTop: scrollAmount
			}, PAGE.scrollSpeed);
		}
	};
	
	// stored shit
	PAGE.localStorageKey = PAGE.localStorageKeyPrefix + PAGE.comicsName;
	PAGE.localStorageKeyPage = PAGE.localStorageKey + '*';
	
	
	PAGE.SessCacheQuery = function(page){
		var r = window.sessionStorage.getItem( PAGE.localStorageKeyPage + page );
		if(!r)return false;
		try{
			r = JSON.parse( r );
		} catch(e){
			return false;
		}
		return r;
	};
	PAGE.SessCachePut = function(page,data){
		var d = JSON.stringify( data );
		window.sessionStorage.setItem( PAGE.localStorageKeyPage + page , d );
	};
	
	
	PAGE.store = function(){
		window.localStorage.setItem( PAGE.localStorageKey, PAGE.comicsPage );
	};
	window.eval('window.z_SetPage=function(){ $(window).trigger(\''+
		PAGE.localStorageKeyPrefix+':setpage'
	+'\') };')
	PAGE.storePage = function(){ // z_SetPage
		var p = parseInt( prompt('Set page to:', PAGE.comicsPage), 10 )
		if( isNaN(p) || p<1 || p>PAGE.comicsLastPage ){
			alert('Wrong page!\nMust be: 1 < page < '+PAGE.comicsLastPage);
			return;
		}
		if(!confirm('Warning! Really update page from '+PAGE.comicsPage+' to '+p+' ?')){
			return;
		}
		PAGE.wantPage = p;
		PAGE.ShouldIDoSomething();
	};
	$(window).on(PAGE.localStorageKeyPrefix+':setpage',PAGE.storePage);
	
	var stored = window.localStorage.getItem( PAGE.localStorageKey );
	if(stored){ stored = parseInt(stored)||false; } else {stored=false;}
	if( stored && (stored != PAGE.comicsPage) ){
		location.href = PAGE.makeUrl(stored);
		return;
	}
	PAGE.stored = stored;
	delete stored;
	
	var curr = PAGE.parsePageString( $('html')[0].outerHTML );
	if( !curr ){ return; }
	
	PAGE.comicsLastPage = curr.LastPage;
	PAGE.comicsPageTitle = curr.Title;
	
	if(PAGE.comicsPage != curr.Page){
		if(
			confirm(
				'Что-то пошло не так.'
				+'\n'
				+'\n[1] Сохраненная страница:\t'+PAGE.comicsPage
				+'\n[2] Страница комикса (html):\t'+curr.Page
				+'\n[3] Максимальная страница (html):\t'+PAGE.comicsLastPage
				+'\n'
				+'\nЗаменить сохраненную страницу '+PAGE.comicsPage+' на '+curr.Page+'?'
			)
		){
			PAGE.wantPage = PAGE.comicsPage = curr.Page;
			PAGE.store();
			location.href = PAGE.makeUrl(PAGE.comicsPage);
		}
		return;
	}
	
	
	PAGE.wantPage = PAGE.comicsPage;
	setTimeout(function(){
		PAGE.swapPage();
	},1);
	
	
	// {
		// "Page" : 1,
		// "LastPage" : 741,
		// "Image" : "/upload/!c/!import/unsounded/000001-go44gzvmk6.jpg",
		// "ContentSerialNomargin" : "\t",
		// "ContentMargin" : "\t"
	// }
	
	PAGE.handleSwap = function(page, o){
		PAGE.log('page.swap: swapping page to #'+page+(
			o.Preloaded?'':' which doesn\'t have preloaded image'
		));
		PAGE.$contentMargin.html( o.ContentMargin );
		PAGE.$contentSer.html( o.ContentSerialNomargin );
		
		// title
		PAGE.comicsPageTitle = o.Title;
		document.title = '#'+PAGE.comicsPage+' | '+PAGE.comicsPageTitle;
		
		PAGE.comicsPage = page;
		// $(window).scrollTop(0);
		PAGE.scroll(false, 0);
		PAGE.changeHandlers();
	}
	
	PAGE.plData = Object.create(null);
	
	PAGE.wantPage = PAGE.comicsPage;
	
	PAGE.putCached = function(page,data){
		PAGE.plData[ page ] = data;
		PAGE.SessCachePut( page, data );
		PAGE.putCachedPreloadImage( page );
	};
	PAGE.putCachedPreloadImage = function(page){
		PAGE.plData[ page ].Preloaded = false;
		PAGE.plData[ page ].DomImage = new Image();
		PAGE.plData[ page ].DomImage.onerror = function(){
			console.error('Cannot load image #'+page+' (window._err_img): '+PAGE.plData[ page ].Image);
			window._err_img = PAGE.plData[ page ].Image;
			if( typeof( PAGE.plData[ page ] )!='undefined' ){
				delete PAGE.plData[ page ];
			}
		};
		var log = false;
		PAGE.plData[ page ].DomImage.onload = function(){
			delete PAGE.plData[ page ].DomImage.onload;
			
			if( typeof( PAGE.plData[ page ] )=='object' ){
				if(log){
					PAGE.log('page.cache: IMG preloaded #'+page);
				}
				PAGE.plData[ page ].Preloaded = true;
			} else {
				PAGE.log('page.cache: IMG preloaded #'+page+' but OBJ DOES NOT EXISTS!!');
			}
		};
		PAGE.plData[ page ].DomImage.src = PAGE.plData[ page ].Image;
		setTimeout(function(){ log=true; },30);
	};
	PAGE.putCached( PAGE.comicsPage, curr );
	delete curr;
	
	PAGE.$contentMargin = $('#contentMargin');
	PAGE.$content = $('#content');
	PAGE.$contentSer = $('#content > div.serial-nomargin');
	
	
	$('#common').remove();
	$('#background > div').not('#container').remove();
	$('#container > header.serial').remove();
	$('#container > nav.serial').remove();
	
	$('#contentSide').remove();
	
	// custom stylesheets
	$('<style/>').attr('type','text/css').html(''
		+' #content.notitle h3.serial {display:none;}'
		+' section.issue img {max-width: none;}'
		+' div#container { width: auto; display:inline-block; min-width:'+$('div#container').css('width')+' }' // background-color: transparent;
		+' #background{text-align:center;}'
		+' #container{text-align:left;}'
	).appendTo('body');
	
	// $('#content > div.serial-nomargin > h3.serial').remove();
	
	PAGE.$content.addClass('notitle');
	if( PAGE.contentMarginMover ){
		PAGE.$contentMargin
			.detach()
			.css({
				position:'absolute',
				left:'5px',
				top:'64px',
				border:'1px #000 solid',
				background:'#fff'
			})
			.appendTo('body')
			.hide();
	}
	PAGE.gcAllowedSet = function(){ PAGE.gcAllowed = true; }; PAGE.gcAllowedSet();
	PAGE.gc = function(){
		if( !PAGE.gcAllowed ){ return; }
		
		var r = PAGE.populateList(5);
		r.push( PAGE.comicsPage );
		for( var page in PAGE.plData ){
			page = parseInt(page,10);
			if( $.inArray( page, r ) == -1 ){
				PAGE.log('page.gc: removing old page #'+page);
				delete PAGE.plData[ page ];
				window.sessionStorage.removeItem(PAGE.localStorageKeyPage + page);
			}
		}
		
		var prefixl = PAGE.localStorageKeyPage.length;
		for( var i = window.sessionStorage.length; i-->0; ){
			var k = window.sessionStorage.key(i);
			if( typeof(k)=='string' && k.indexOf(PAGE.localStorageKeyPage)==0 ){
				var page = parseInt(k.substr(prefixl),10);
				if( $.inArray( page, r ) == -1 ){
					PAGE.log('page.gc: removing sessionStorage page #'+page);
					window.sessionStorage.removeItem(PAGE.localStorageKeyPage + page);
				}
			}
		}
		// key()
		PAGE.gcAllowed = false;
		setTimeout( PAGE.gcAllowedSet, 10000 );
	};
	PAGE.swapPage = function(){
		var page = PAGE.wantPage;
		if( typeof( PAGE.plData[ page ] )=='undefined' ){
			PAGE.log('page.swap: NO CACHE FOR #'+page);
			return false;
		}
		if( typeof( PAGE.plData[ page ] )=='boolean' ){
			PAGE.log('page.swap: CACHE STILL WAITING #'+page);
			return true;
		}
		if( typeof( PAGE.plData[ page ] )=='object' ){
			var o = PAGE.plData[ page ];
			PAGE.handleSwap(page, o);
		}
		return true;
	}
	PAGE.ShouldIDoSomething = function(){
		if( PAGE.wantPage < 1 ){
			PAGE.log('page.swap: wrong wantPage = '+PAGE.wantPage);
			PAGE.wantPage = 1;
		} else if( PAGE.wantPage > PAGE.comicsLastPage ){
			PAGE.log('page.swap: wrong wantPage = '+PAGE.wantPage);
			PAGE.wantPage = PAGE.comicsLastPage;
		}
		if( PAGE.wantPage != PAGE.comicsPage ){
			if(!PAGE.swapPage()){
				PAGE.log('page.cache: requesting non-preloaded page #'+page);
				PAGE.ajaxPreload( PAGE.wantPage );
				return true;
			}
		}
		
		var r = PAGE.populateList(0);
		var rl = r.length;
		for( var i=0; i<rl; i++ ){
			var page = r[i];
			if( typeof( PAGE.plData[ page ] )=='undefined' ){
				var cached = PAGE.ajaxPreload( page );
				if(!cached){
					PAGE.log('page.cache: preloading page #'+page);
					return true;
				}
			}
		}
		PAGE.gc();
		return false;
	};
	PAGE.ticker = function(){
		var to = PAGE.ShouldIDoSomething()?300:1000;
		PAGE.tickerTO = setTimeout(PAGE.ticker, to);
	};
	PAGE.tickerTO = setTimeout(PAGE.ticker,10);
	
	
	PAGE.populateList = function(Add){
		var a = [];
		for( var i=1; i<=(4+Add); i++ ){
			var np = PAGE.comicsPage+i;
			if( np <= PAGE.comicsLastPage ){
				a.push(np);
			}
		}
		for( var i=1; i<=(2+Add); i++ ){
			var np = PAGE.comicsPage-i;
			if( np >= 1 ){
				a.push(np);
			}
		}
		return a;
	};
	
	PAGE.ajaxPreload = function(page){ // return cached
		var sc = PAGE.SessCacheQuery(page);
		if(sc){
			PAGE.plData[ page ] = sc;
			// PAGE.SessCachePut( page, data );
			PAGE.putCachedPreloadImage( page );
			return true;
		}
		
		PAGE.plData[ page ] = true;
		$.ajax({
			type:'GET',
			dataType:'text',
			cache:true,
			url:PAGE.makeUrl( page ),
			timeout:PAGE.AjaxRequestTimeoutMs,
			error:function(){
				if( typeof( PAGE.plData[ page ] )!='undefined' ){
					delete PAGE.plData[ page ];
				}
			},
			success:function(d){
				var parsed = PAGE.parsePageString( d );
				if(!parsed){
					console.error('Cannot parse data (see window._err_data)');
					window._err_data = d;
					if( typeof( PAGE.plData[ page ] )!='undefined' ){
						delete PAGE.plData[ page ];
					}
				} else {
					PAGE.log('page.ajax: preloaded #'+page);
					PAGE.putCached(page,parsed);
					PAGE.ShouldIDoSomething();
				}
			}
		});
		
		return false;
	};
	
	PAGE.handlePrev = function(){
		// PAGE.wantPage = PAGE.comicsPage;
		PAGE.wantPage--;
		PAGE.ShouldIDoSomething();
	};
	PAGE.handleNext = function(){
		PAGE.wantPage++;
		PAGE.ShouldIDoSomething();
	};
	
	var uparrow_pressed = false;
	var last_scroll = 0;
	
	var scroll_faster = PAGE.scrollFasterDefault;
	$(document).keydown(function(e){
		var prevent = true;
		// if( e.which==13 && e.shiftKey ) { // Shift+Enter
		// } else
		if( (e.which==38 || e.which==40) && e.shiftKey ) { // ^/v
			scroll_faster = !scroll_faster;
		}
		if( e.which==37 ){ // <
			if( PAGE.contentMarginMover ){PAGE.$contentMargin.hide();} PAGE.$content.addClass('notitle');
			if( uparrow_pressed ){
				if( PAGE.contentMarginMover ){ $(window).scrollTop( last_scroll ); }
			} else {
				PAGE.handlePrev();
			}
		} else if ( e.which==39 ){ // >
			if( uparrow_pressed ){
				if( PAGE.contentMarginMover ){PAGE.$contentMargin.show();} PAGE.$content.removeClass('notitle');
				// $(window).scrollTop(0);
				PAGE.scroll(false, 0);
			} else {
				if( PAGE.contentMarginMover ){PAGE.$contentMargin.hide();} PAGE.$content.addClass('notitle');
				PAGE.handleNext();
			}
		} else if ( e.which==38 ){ // ^
			uparrow_pressed = true;
			last_scroll = $(window).scrollTop();
			if( PAGE.scrollFasterPx && scroll_faster ){
				// $(window).scrollTop( Math.max( 0, $(window).scrollTop()-PAGE.scrollFasterPx ) );
				PAGE.scroll( true, -(e.ctrlKey?PAGE.scrollFasterCtrlPx:PAGE.scrollFasterPx) );
			} else {
				prevent = false;
			}
		} else if ( e.which==40 ){ // v
			if( PAGE.scrollFasterPx && scroll_faster ){
				// $(window).scrollTop( $(window).scrollTop()+PAGE.scrollFasterPx );
				PAGE.scroll( true, (e.ctrlKey?PAGE.scrollFasterCtrlPx:PAGE.scrollFasterPx) );
			} else {
				prevent = false;
			}
		} else {
			prevent = false;
		}
		if(prevent){e.preventDefault();return false;}
	}).keyup(function(e){
		if ( e.which==38 ){ // ^
			uparrow_pressed = false;
		}
	});
	
	PAGE.$contentSer.on('click','a',function(){
		var pn = this.pathname;
		if( pn == PAGE.makeUrl( PAGE.comicsPage+1 ) ){
			PAGE.handleNext();
			return false;
		} else if ( PAGE.makeUrl( PAGE.comicsPage-1 ) ) {
			PAGE.handlePrev();
			return false;
		}
	});
	
	$(window).on('beforeunload', function(){
		return 'You shall not pass.';
	});
	
	PAGE.log('init');
};




PAGE.removeScripts = (function(){
	var dangerous_tags = (['script', 'style', 'link', 'embed', 'object'].join(', '));
	var removeInlineHandlers = function(element){
		// http://stackoverflow.com/a/3593250 http://stackoverflow.com/q/3593242 http://stackoverflow.com/questions/3593242/how-to-remove-all-attributes-from-body-with-js-or-jquery
		for( var i = element.attributes.length; i-->0; ){
			var attr = element.attributes[i];
			if( attr.nodeName.toLowerCase().indexOf('on')==0 ){
				element.removeAttributeNode(attr);
			}
		}
	};
	var removeScripts = function(el){
		var f;
		while( f = el.querySelector(dangerous_tags) ){ // we querying selector every time because tags can contain each other
			f.parentNode.removeChild(f);
		}
		var f = el.querySelectorAll('*');
		for(var i=f.length; i-->0; ){
			removeInlineHandlers( f[i] );
		}
	};
	return removeScripts;
})();

// Да простят меня авторы. Серьёзно, это уже порядком поднадоело.
var rx1 = /(?:(?:Мой )?(?:патреон|яндекс|yandex|paypal|wm(?:z|r|e|u)|кошелек|счет)[\s.-]*(?:кошелек|money|деньги)?:?|(?:https?:\/\/)?(?:www\.)?patreon.com\/[^\s]*|41\d{13}\b|(?:wm)?(?:z|r|e|u)\d{12}\b)/gi;
var rx2 = /(?:(?:\s*(?:<p>\s*<\/p>|<br ?\/? ?>)\s*)+|^(?:\s*<br ?\/? ?>)+|(?:<br ?\/? ?>\s*)+$)/gi;
PAGE.parsePageString = function(s){
	var o={};
	var parser = new DOMParser();
	var d = parser.parseFromString(s, "text/html");
	
	var x = d.querySelector('#content span.button.center a[onclick^="jumpTo"]');
	if(!x){return false;}
	x=$.trim(x.innerHTML).match(/^(\d+)\/(\d+)$/);
	if(!x){return false;}
	o.Page = parseInt(x[1]);
	o.LastPage = parseInt(x[2]);
	delete x;
	
	var x = d.querySelector('#contentMargin > div.forum');
		if(x){ x.parentNode.removeChild(x) }; delete x;
	var x = d.querySelector('#contentMargin > form');
		if(x){ x.parentNode.removeChild(x) }; delete x;
	var x = d.querySelector('#contentMargin > article.authors > .social');
		if(x){ x.parentNode.removeChild(x) }; delete x;
	// var x = d.querySelectorAll('#contentMargin > article.authors > div.description > p');
	// for(var i=x.length;i-->0;){
		// var T = $.trim(x[i].innerText);
		// var t = $.trim(T.replace(rx,''));
		// if( t == T ){continue;}
		// if( h == '' ){ x[i].parentNode.removeChild(x[i]);continue; }
		// var h = x[i].innerHTML.replace(rx,'');
		// x[i].innerHTML = h;
	// }
	var x = d.querySelector('#contentMargin > article.authors > div.description');
	if(x){ x.innerHTML = x.innerHTML.replace(rx1,'').replace(rx2,''); }
	delete x;
	
	var x = d.querySelector('#content > div.serial-nomargin #mainImage').getAttribute('src');
	o.Image = x;
	delete x;
	
	var x = d.querySelector('#content > div.serial-nomargin');
	PAGE.removeScripts(x);
	o.ContentSerialNomargin = x.innerHTML;
	delete x;
	
	var x = d.querySelector('#contentMargin');
	PAGE.removeScripts(x);
	o.ContentMargin = x.innerHTML;
	delete x;
	
	var x = d.querySelector('title');
	o.Title = x?( $.trim( x.innerText ) ):'?';
	delete x;

	return o;
};

(function(){
	
	var m = /^\/~([^\/]+)\/(\d*)(?:\D|$)/.exec( location.pathname.toString() );
	if(!m){return;}
	
	if(!window.$){
		console.log('where is my $, billy ??');
		return;
	}
	
	var d = $('<div/>');
	var b = $('<button/>');
	b.html('Запуск читалки').click(function(){
		d.remove();
		PAGE.init();
		// w.history.pushState({a:location.href}, "* Супер-читалка", location.href);
	}).appendTo(d);
	d.css({
		borderRadius:'4px',
		position:'fixed', // absolute
		zIndex:1e6,
		right:'2px',
		top:'2px',
		padding:'4px',
		background:'rgba(0,0,0,0.6)',
		border:'2px rgba(0,0,0,0.9) solid'
	}).appendTo('body');
})();


*/});
var s=document.createElement('script');s.type='text/javascript';s.innerHTML=a;document.body.appendChild(s);
// textContent instead of innerHTML?

})();

QingJ © 2025

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