// ==UserScript==
// @name Enhanced viewer for acomics.ru
// @name:ru Улучшенный просмотрщик для acomics.ru
// @description:ru Предзагрузка, удобная навигация и прочие улучшения для сайта acomics.ru
// @description Preload, navigation and other enhancements for acomics.ru comics viewer
// @author Sanya_Zol (https://github.com/SanyaZol)
// @license Unlicense
// @icon data:image/gif;base64,R0lGODlhIAAgAMQAAP////22bNMQNf/MXP63WOprSP/DWPvQsP/gZ/7Hl/CFTOjazv7hzvzAgP/VXdgkONK9udeylN3Nwujj4OdWRPzx6uDDp/Hr5/Px8Pv18vv5+f/uedDBwea6cvehWOA8PSH5BAAAAAAALAAAAAAgACAAAAX/ICCOopQwWaWR7LgkSdMErdgQQXJg9XhVt8GAQKhNhAZCo9IDXGYDxMYRrVkGG4QhwFjVIA6EdINFtCYEw4ZsOHhbDcTQ4wkEPC2IUhHIJt4kVw4KAoWFHy0dDgEPBVkBFwCAaAQOH4aFeCRHCIQCA4snTC5CHpgCHwMsFgYDlwIKDklcIxM3BhSnsSQLW6aFDwMGw24irAa/hh/DIxkdabmGHlMODSsaDcLRhrEWPkkEpxRUAw0ivUOnD2kSIxLDBacCHsMBBwARYvGYCuUjGAGSPJBXoFW5C4oMDDS0zkCEERyGeVJXacCJbPsMFUBAIIEIDBFaLZTXbwuDCYwwyzXs+DHgRHnLWh3IcGCkgJUNMmhIkOQVQ0z0yh1okLHQxiEnhSWTV2jcIhkpGRqQFSACjm2oCmAVUKkjtq0bqSKzqaCBAZ8CClBpY2HpTQJy0hR9MKzBy3VaAlQ4sDXWWrIOOgAkq4UAAwZug4W5W8mChg5FPzwKMMFCXwSWMI2zgEFD21NxtvBwm+rlPAcLRFyIgFWtAW8SAqCdh/ZDBwupP0Y4Rc+bBpCnPnAYPlxCbhbDIXCAYDwSROUQIkBoQr269evYs2vfXj0EADs=
// @homepageURL https://greasyfork.org/ru/scripts/10521
// @supportURL https://greasyfork.org/ru/scripts/10521
// @namespace Sanya_Zol
// @version 0.3.0
// @match https://acomics.ru/*
// @run-at document-start
// @grant none
// @require https://code.jquery.com/jquery-3.7.1.min.js
// ==/UserScript==
// @ts-check
// Greasy Fork: https://greasyfork.org/ru/scripts/10521
// Github: https://github.com/SanyaZol/acomics-enhanced-viewer-userscript
/** @typedef {{Page:number,LastPage:number,Image:string|null,ContentSerialNomargin:string,ContentMargin:string,Title:string}} parsedPage */
(function () {
class AcomicsViewer {
settings = {
// Блокировать случайное закрытие страницы
blockUnload: false,
// таймаут запроса в милисекундах (секундах*1000)
AjaxRequestTimeoutMs: 10000,
// чтобы деактивировать или снова активировать быстрый скролл, нажми Shift+[˄] или Shift+[˅]
scrollFasterDefault: true,
// сейчас при скролле страницы стрелками по вертикали [˄] и [˅] будет быстрый скролл на 300 пикселей
scrollFasterPx: 300,
// а при зажатом Ctrl - на 100
scrollFasterCtrlPx: 100,
// время в милисекундах, за которое скроллить при использовании быстрого скролла
scrollFasterSpeed: 75,
// время в милисекундах, за которое скроллить наверх при смене страниц
scrollSpeed: 75,
// выпилить комментарии - они будут вылазить при нажатии [˄]+[˃]
// (стрелки вправо при зажатой стрелке вверх) и выезжать при нажатии [˂]+[˃]
contentMarginMover: false,
// выводить отладочную информацию в левом верхнем углу страницы
visualLog: false,
};
constants = {
eventNamespace: 'acomics-enhanced-viewer-userscript',
// префикс localStorage
localStorageKeyPrefix: '**zol**page**',
logPrefix: '[acViewer] ',
};
stage = 'noInit';
/** @type {JQuery<HTMLElement> | null} */
logOverlay = null;
log(text) {
let s = `[${this.stage}] ${text}`;
if (this.settings.visualLog) {
if (!this.logOverlay) {
this.logOverlay = $('<div/>');
this.logOverlay.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');
}
$('<div/>').text(s).hide().prependTo(this.logOverlay).slideDown(200).delay(5000).slideUp(200, function () { $(this).remove(); });
this.logOverlay.fadeIn().finish().delay(5000).slideUp(200);
}
console.log(`${this.constants.logPrefix}${s}`);
}
preInitFailed = false;
preInitGuard = false;
preInitSucceeded = false;
/** @type {string|null} */
comicsName = null;
/** @type {number|null} */
comicsPage = null;
/**
* @param {number} id
* @returns {string}
*/
makeUrl(id) {
if (!this.comicsName) throw new Error("makeUrl() requires this.comicsName to be set");
if (id === null) throw new Error("makeUrl() requires id to be set");
return '/~' + this.comicsName + '/' + id;
}
/** @type {string|null} */
localStorageKey = null;
/** @type {string|null} */
localStorageKeyPage = null;
/** @returns {void} */
store() {
if (!this.localStorageKey || this.comicsPage === null) throw new Error("store() requires this.localStorageKey to be set");
if (this.comicsPage !== this.wantPage) throw new Error("store() requires this.comicsPage === this.wantPage");
window.localStorage.setItem(this.localStorageKey, `${this.comicsPage}`);
}
/** @type {number|null} */
wantPage = null;
static _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;
static _rx2 = /(?:(?:\s*(?:<p>\s*<\/p>|<br ?\/? ?>)\s*)+|^(?:\s*<br ?\/? ?>)+|(?:<br ?\/? ?>\s*)+$)/gi;
static _dangerous_tags = (['script', 'style', 'link', 'embed', 'object'].join(', '));
static removeInlineHandlers(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);
}
}
}
static removeScripts(el) {
var f;
while (f = el.querySelector(AcomicsViewer._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;) {
AcomicsViewer.removeInlineHandlers(f[i]);
}
}
/**
*
* @param {string} s
* @returns {parsedPage|null}
*/
parsePageString(s) {
// TODO: validate comics page is really from the comics that is in URL
var o = {};
var parser = new DOMParser();
var d = parser.parseFromString(s, "text/html");
{
let x1 = d.querySelector('.common-content .button-goto span');
if (!x1) { return null; }
let x = $.trim(x1.innerHTML).match(/^(\d+)\/(\d+)$/);
if (!x) { return null; }
o.Page = parseInt(x[1]);
o.LastPage = parseInt(x[2]);
}
{
let x = d.querySelector('.common-content .issue-description-buttons');
if (x) { x.parentNode?.removeChild(x); };
}
{
let x = d.querySelector('.common-content .reader-comment-form');
if (x) { x.parentNode?.removeChild(x); };
}
{
let x = d.querySelector('.common-content .reader-issue img.issue')?.getAttribute('src');
o.Image = x || null;
}
{
let x = d.querySelector('.common-content .reader-issue');
if (!x) return null;
AcomicsViewer.removeScripts(x);
o.ContentSerialNomargin = x.innerHTML;
}
{
let x = d.querySelector('.common-content .view-container .view-article');
if (!x) return null;
AcomicsViewer.removeScripts(x);
let y = x.querySelector('.issue-description-text');
if (y) y.innerHTML = y.innerHTML.replace(AcomicsViewer._rx1, '').replace(AcomicsViewer._rx2, '');
o.ContentMargin = x.innerHTML;
}
{
let x = d.querySelector('title');
o.Title = x ? ($.trim(x.innerText)) : '?';
}
return o;
}
/** @type {number|null} */
comicsLastPage = null;
/** @type {number|null} */
init_comicsPage = null;
/** @type {number|null} */
init_wantPage = null;
/** @type {parsedPage|null} */
tmp_curr = null;
/** @returns {boolean} */
preInit() {
if (this.preInitSucceeded) return true;
if (this.preInitFailed || this.preInitGuard) { return false; }
this.preInitFailed = true;
this.preInitGuard = true;
this.stage = 'preInit.1';
{
const m = /^\/~([^\/]+)\/(\d*)(?:\D|$)/.exec(location.pathname.toString());
if (!m) { return false; }
if (!window.$) {
this.log('no window.$');
return false;
}
this.comicsName = m[1];
const page = parseInt(m[2], 10);
if (m[2] == '' || isNaN(page) || page < 1) {
return false;
}
this.comicsPage = page;
}
this.localStorageKey = this.constants.localStorageKeyPrefix + this.comicsName;
this.localStorageKeyPage = this.localStorageKey + '*';
{
/** @var {number|null} */
let stored = null;
const storedString = window.localStorage.getItem(this.localStorageKey);
if (storedString) {
stored = parseInt(storedString, 10) || null;
}
if (stored !== null && stored != this.comicsPage) {
this.wantPage = stored;
} else {
this.wantPage = this.comicsPage;
}
}
this.stage = 'preInit.2';
let curr = this.parsePageString($('html')[0].outerHTML);
if (!curr) { return false; }
this.comicsLastPage = curr.LastPage;
this.comicsPageTitle = curr.Title;
this.init_comicsPage = this.comicsPage;
this.init_wantPage = this.wantPage;
this.stage = 'preInit.3';
if (this.comicsPage != curr.Page) {
if (
confirm(
'Что-то пошло не так.'
+ '\n'
+ '\n[1] Сохраненная страница:\t' + this.comicsPage
+ '\n[2] Страница комикса (html):\t' + curr.Page
+ '\n[3] Максимальная страница (html):\t' + this.comicsLastPage
+ '\n'
+ '\nЗаменить сохраненную страницу ' + this.comicsPage + ' на ' + curr.Page + '?'
)
) {
this.wantPage = this.comicsPage = curr.Page;
this.store();
location.href = this.makeUrl(this.comicsPage);
}
return false;
}
this.tmp_curr = curr;
// this.putCached( this.comicsPage, curr );
// this.putCached( this.tmp_curr.Page, this.tmp_curr ); delete this.tmp_curr;
this.stage = 'preInit.4';
this.preInitSucceeded = true;
return true;
}
initSucceeded = false;
initFailed = false;
initGuard = false;
noPushState = false;
firstPushState = false;
changeHandlers() {
this.store();
this.ShouldIDoSomething();
if (this.noPushState) {
this.noPushState = false;
return;
}
let stateObj = { page: this.comicsPage };
let title = `#${this.comicsPage} | ${this.comicsPageTitle}`;
let url = this.makeUrl(this.comicsPage);
if (this.firstPushState) {
this.firstPushState = false;
history.replaceState(stateObj, title, url);
} else {
history.pushState(stateObj, title, url);
}
}
$htmlbody = null;
doScroll(relative, scrollAmount) {
this.$htmlbody || (this.$htmlbody = $('html,body'));
if (relative) {
this.$htmlbody.finish().animate({
scrollTop: Math.max(0, $(window).scrollTop() + scrollAmount)
}, this.settings.scrollFasterSpeed);
} else {
this.$htmlbody.finish().animate({
scrollTop: scrollAmount
}, this.settings.scrollSpeed);
}
}
SessCacheQuery(page) {
if (!this.localStorageKeyPage) throw new Error("No localStorageKeyPage");
var r = window.sessionStorage.getItem(this.localStorageKeyPage + page);
if (!r) return false;
try {
r = JSON.parse(r);
} catch (e) {
return false;
}
return r;
};
SessCachePut(page, data) {
if (!this.localStorageKeyPage) throw new Error("No localStorageKeyPage");
var d = JSON.stringify(data);
window.sessionStorage.setItem(this.localStorageKeyPage + page, d);
};
/** @type {number|null} */
handleSwapTimeout = null;
handleSwap(page, o) {
this.log('page.swap: swapping page to #' + page + (
o.Preloaded ? '' : ' which doesn\'t have preloaded image'
));
this.$contentMargin.html(o.ContentMargin);
this.$contentSer.find('img.issue').attr('src', o.Image);
if (this.handleSwapTimeout !== null) clearTimeout(this.handleSwapTimeout);
this.handleSwapTimeout = setTimeout(() => {
this.$contentSer.html(o.ContentSerialNomargin);
this.handleSwapTimeout = null;
}, 50);
this.$contentCounter.html(`${o.Page}/${o.LastPage}`);
if (o.Page < 2) this.$contentBtnPrev.addClass('button-inactive'); else this.$contentBtnPrev.removeClass('button-inactive');
if (o.Page >= o.LastPage) this.$contentBtnNext.addClass('button-inactive'); else this.$contentBtnNext.removeClass('button-inactive');
// title
this.comicsPageTitle = o.Title;
this.comicsPage = page;
document.title = '#' + this.comicsPage + ' | ' + this.comicsPageTitle;
// $(window).scrollTop(0);
this.doScroll(false, 0);
this.changeHandlers();
};
/** @type {Object} */
plData = Object.create(null);
putCached(page, data) {
this.plData[page] = data;
this.SessCachePut(page, data);
this.putCachedPreloadImage(page);
};
putCachedPreloadImage(page) {
this.plData[page].Preloaded = false;
this.plData[page].DomImage = new Image();
this.plData[page].DomImage.onerror = (err) => {
console.error('Cannot load image #' + page + ' (window._err_img): ' + this.plData[page].Image);
console.error({ "this.plData[page].Image": this.plData[page].Image, "err (event)": err });
// TODO: debugger;
window._err_img = this.plData[page].Image;
if (typeof (this.plData[page]) != 'undefined') {
delete this.plData[page];
}
};
var log = false;
this.plData[page].DomImage.onload = () => {
delete this.plData[page].DomImage.onload;
if (typeof (this.plData[page]) == 'object') {
if (log) {
this.log('page.cache: IMG preloaded #' + page);
}
this.plData[page].Preloaded = true;
} else {
this.log('page.cache: IMG preloaded #' + page + ' but OBJ DOES NOT EXISTS!!');
}
};
this.plData[page].DomImage.src = this.plData[page].Image;
setTimeout(() => { log = true; }, 30);
};
/** @type {JQuery<HTMLElement>|null} */
$contentMargin = null;
/** @type {JQuery<HTMLElement>|null} */
$content = null;
/** @type {JQuery<HTMLElement>|null} */
$contentSer = null;
/** @type {JQuery<HTMLImageElement>|null} */
$contentImage = null;
/** @type {JQuery<HTMLElement>|null} */
$contentCounter = null;
/** @type {JQuery<HTMLElement>|null} */
$contentBtnPrev = $('.common-content .button-previous');
/** @type {JQuery<HTMLElement>|null} */
$contentBtnNext = $('.common-content .button-next');
gcAllowed = false;
gcAllowedSet() { this.gcAllowed = true; }
gc() {
if (!this.gcAllowed) { return; }
var r = this.populateList(5);
r.push(this.wantPage);
for (var page_str in this.plData) {
page = parseInt(page_str, 10);
if ($.inArray(page, r) == -1) {
this.log('this.gc: removing old page #' + page);
delete this.plData[page];
window.sessionStorage.removeItem(this.localStorageKeyPage + page);
}
}
var prefixl = this.localStorageKeyPage.length;
for (var i = window.sessionStorage.length; i-- > 0;) {
var k = window.sessionStorage.key(i);
if (typeof (k) == 'string' && k.indexOf(this.localStorageKeyPage) == 0) {
var page = parseInt(k.substr(prefixl), 10);
if ($.inArray(page, r) == -1) {
this.log('this.gc: removing sessionStorage page #' + page);
window.sessionStorage.removeItem(this.localStorageKeyPage + page);
}
}
}
// key()
this.gcAllowed = false;
setTimeout(() => this.gcAllowedSet(), 10000);
};
swapPage() {
var page = this.wantPage;
if (typeof (this.plData[page]) == 'undefined') {
this.log('page.swap: NO CACHE FOR #' + page);
return false;
}
if (typeof (this.plData[page]) == 'boolean') {
this.log('page.swap: CACHE STILL WAITING #' + page);
return true;
}
if (typeof (this.plData[page]) == 'object') {
var o = this.plData[page];
this.handleSwap(page, o);
}
return true;
};
ShouldIDoSomething() {
if (this.wantPage < 1) {
this.log('page.swap: wrong wantPage = ' + this.wantPage);
this.wantPage = 1;
} else if (this.wantPage > this.comicsLastPage) {
this.log('page.swap: wrong wantPage = ' + this.wantPage);
this.wantPage = this.comicsLastPage;
}
if (this.wantPage != this.comicsPage) {
if (!this.swapPage()) {
this.log('page.cache: requesting non-preloaded page #' + this.wantPage);
this.ajaxPreload(this.wantPage);
return true;
}
}
var r = this.populateList(0);
var rl = r.length;
for (var i = 0; i < rl; i++) {
var page = r[i];
if (typeof (this.plData[page]) == 'undefined') {
var cached = this.ajaxPreload(page);
if (!cached) {
this.log('page.cache: preloading page #' + page);
return true;
}
}
}
this.gc();
return false;
};
ticker() {
var to = this.ShouldIDoSomething() ? 300 : 1000;
this.tickerTO = setTimeout(() => this.ticker(), to);
};
populateList(Add) {
var a = [];
for (var i = 1; i <= (4 + Add); i++) {
var np = this.wantPage + i;
if (np <= this.comicsLastPage) {
a.push(np);
}
}
for (var i = 1; i <= (2 + Add); i++) {
var np = this.wantPage - i;
if (np >= 1) {
a.push(np);
}
}
return a;
};
ajaxPreload(page) { // return cached
var sc = this.SessCacheQuery(page);
if (sc) {
this.plData[page] = sc;
// this.SessCachePut( page, data );
this.putCachedPreloadImage(page);
return true;
}
this.plData[page] = true;
$.ajax({
type: 'GET',
dataType: 'text',
cache: true,
url: this.makeUrl(page),
timeout: this.settings.AjaxRequestTimeoutMs,
error: (...args) => {
console.error({ _: `ajaxPreload(${page}) failed!`, args });
if (typeof (this.plData[page]) != 'undefined') {
delete this.plData[page];
}
},
success: (d) => {
var parsed = this.parsePageString(d);
if (!parsed) {
console.error('Cannot parse data (see window._err_data)');
window._err_data = d;
if (typeof (this.plData[page]) != 'undefined') {
delete this.plData[page];
}
} else {
this.log('page.ajax: preloaded #' + page);
this.putCached(page, parsed);
this.ShouldIDoSomething();
}
}
});
return false;
};
handlePrev() {
// this.wantPage = this.comicsPage;
this.wantPage--;
this.ShouldIDoSomething();
};
handleNext() {
this.wantPage++;
this.ShouldIDoSomething();
};
uparrow_pressed = false;
last_scroll = 0;
documentKeydown(e) {
var prevent = true;
// if( e.which==13 && e.shiftKey ) { // Shift+Enter
// } else
if ((e.which == 38 || e.which == 40) && e.shiftKey) { // ^/v
this.scroll_faster = !this.scroll_faster;
}
if (e.which == 37) { // <
if (this.settings.contentMarginMover) { this.$contentMargin.hide(); }
if (this.uparrow_pressed) {
if (this.settings.contentMarginMover) { $(window).scrollTop(this.last_scroll); }
this.$content.addClass('notitle');
} else {
this.handlePrev();
}
} else if (e.which == 39) { // >
if (this.uparrow_pressed) {
if (this.settings.contentMarginMover) { this.$contentMargin.show(); }
this.$content.removeClass('notitle');
// $(window).scrollTop(0);
this.doScroll(false, 0);
} else {
if (this.settings.contentMarginMover) { this.$contentMargin.hide(); }
this.handleNext();
}
} else if (e.which == 38) { // ^
this.uparrow_pressed = true;
this.last_scroll = $(window).scrollTop();
if (this.settings.scrollFasterPx && this.scroll_faster) {
// $(window).scrollTop( Math.max( 0, $(window).scrollTop()-this.settings.scrollFasterPx ) );
this.doScroll(true, -(e.ctrlKey ? this.settings.scrollFasterCtrlPx : this.settings.scrollFasterPx));
} else {
prevent = false;
}
} else if (e.which == 40) { // v
if (this.settings.scrollFasterPx && this.scroll_faster) {
// $(window).scrollTop( $(window).scrollTop()+this.settings.scrollFasterPx );
this.doScroll(true, (e.ctrlKey ? this.settings.scrollFasterCtrlPx : this.settings.scrollFasterPx));
} else {
prevent = false;
}
} else {
prevent = false;
}
if (prevent) { e.preventDefault(); return false; }
}
documentKeyup(e) {
if (e.which == 38) { // ^
this.uparrow_pressed = false;
}
}
scroll_faster = false;
/** @returns {boolean} */
init() {
if (!this.preInit()) { return false; }
if (this.initSucceeded) return true;
if (this.initFailed || this.initGuard) { return false; }
this.initFailed = true;
this.initGuard = true;
this.stage = 'init.1';
this.noPushState = false;
// this.firstPushState = true;
$(window)
.off(`popstate.${this.constants.eventNamespace}`)
.on(`popstate.${this.constants.eventNamespace}`, (e) => {
var d = e?.originalEvent?.state || false;
if (d && d.page) {
this.wantPage = d.page;
this.noPushState = true;
this.ShouldIDoSomething();
}
});
// TODO: add button and click event for this thing and script settings
window.eval('window.z_SetPage=function(){ $(window).trigger(\'' +
this.constants.localStorageKeyPrefix + ':setpage'
+ '\') };');
this.storePage = () => { // z_SetPage
var p = parseInt(prompt('Set page to:', this.comicsPage), 10);
if (isNaN(p) || p < 1 || p > this.comicsLastPage) {
alert('Wrong page!\nMust be: 1 < page < ' + this.comicsLastPage);
return;
}
if (!confirm('Warning! Really update page from ' + this.comicsPage + ' to ' + p + ' ?')) {
return;
}
this.wantPage = p;
this.ShouldIDoSomething();
};
$(window).on(this.constants.localStorageKeyPrefix + ':setpage', this.storePage);
// this.wantPage = this.comicsPage;
setTimeout(() => {
if (this.wantPage == this.comicsPage) {
this.swapPage();
} else {
this.ShouldIDoSomething();
}
}, 1);
this.plData = Object.create(null);
// this.wantPage = this.comicsPage;
this.$content = $('.common-content');
this.$contentMargin = $('.common-content .view-container .view-article');
this.$contentSer = $('.common-content .reader-issue');
// this.$contentImage = $('.common-content .reader-issue img.issue');
this.$contentCounter = $('.common-content .button-goto span, .common-content .reader-issue-title > .number-without-name');
this.$contentBtnPrev = $('.common-content .button-previous');
this.$contentBtnNext = $('.common-content .button-next');
// custom stylesheets
$('<style/>').attr('type', 'text/css').html(''
+ ' .common-header-background, .common-header {display:none !important;}'
+ ' .common-content > .serial-header, .common-content > .serial-reader-menu {display:none;}'
+ ' .common-content .reader-issue-title > a, .common-content #title > a {display:none;}'
+ ' .common-content .reader-issue-title, .common-content #title {padding:0 !important;min-height:0 !important;}'
+ ' .common-content.notitle .reader-issue-title, .common-content.notitle #title {display:none;}'
// + ' .common-content img.issue {max-width: none !important; width: auto; }'
+ ' .page-margins {max-width: none !important;}'
+ ' .page-margins {background-color: transparent !important;}'
+ ' div.page-background {padding-top: 0 !important;}'
+ ' .common-footer {display:none;}'
+ ' body {grid-template-rows: 1fr !important;}'
+ ' .view-container {max-width:var(--max-width);margin-right:auto;margin-left:auto;background-color:#fff;box-shadow:0 3px 6px 1px rgba(0,0,0,0.05);}'
+ ' .common-content .reader-navigator .button-content>* {display:none;}'
+ ' .common-content .reader-navigator .button-first>* {display:none;}'
+ ' .common-content .reader-navigator .button-last>* {display:none;}'
+ ' .common-content .reader-navigator .button-random>* {display:none;}'
).appendTo('body');
this.$content.addClass('notitle');
if (this.settings.contentMarginMover) {
this.$contentMargin
.detach()
.css({
position: 'absolute',
left: '5px',
top: '64px',
border: '1px #000 solid',
background: '#fff'
})
.appendTo('body')
.hide();
}
this.gcAllowedSet();
this.tickerTO = setTimeout(() => this.ticker(), 10);
this.uparrow_pressed = false;
this.last_scroll = 0;
this.scroll_faster = this.settings.scrollFasterDefault;
$(document)
.off(`keydown.${this.constants.eventNamespace}`)
.on(`keydown.${this.constants.eventNamespace}`, (e) => this.documentKeydown(e))
.off(`keyup.${this.constants.eventNamespace}`)
.on(`keyup.${this.constants.eventNamespace}`, (e) => this.documentKeyup(e))
;
this.$contentSer
.off(`click.${this.constants.eventNamespace}`, 'a.reader-issue-next')
.on(`click.${this.constants.eventNamespace}`, 'a.reader-issue-next', (e) => { e.preventDefault(); this.handleNext(); });
this.$contentSer
.off(`click.${this.constants.eventNamespace}`, 'a.reader-issue-previous')
.on(`click.${this.constants.eventNamespace}`, 'a.reader-issue-previous', (e) => { e.preventDefault(); this.handlePrev(); });
this.$contentBtnPrev.find('a')
.attr('href', '#js-prev')
.off(`click.${this.constants.eventNamespace}`)
.on(`click.${this.constants.eventNamespace}`, (e) => {
e.preventDefault();
this.handlePrev();
return false;
});
this.$contentBtnNext.find('a')
.attr('href', '#js-next')
.off(`click.${this.constants.eventNamespace}`)
.on(`click.${this.constants.eventNamespace}`, (e) => {
e.preventDefault();
this.handleNext();
return false;
});
$(window)
.off(`beforeunload.${this.constants.eventNamespace}`)
.on(`beforeunload.${this.constants.eventNamespace}`, (event) => {
if (this.settings.blockUnload) {
event.preventDefault();
return 'You shall not pass.';
}
});
this.putCached(this.tmp_curr.Page, this.tmp_curr);
this.tmp_curr = null;
enableIntercept = true;
this.stage = 'init.2';
this.log('init(finish)');
};
createRunInterface() {
var current = this.init_comicsPage == this.init_wantPage;
var label = 'Запуск читалки';
if (!current) {
label = 'Продолжить чтение (стр. ' + this.init_wantPage + ')';
}
var d = $('<div/>');
$('<button/>').html('×').css({
color: '#F00', fontWeight: 'bold', fontSize: '16px',
position: 'absolute', left: '-10px', top: '-10px', width: '20px', height: '20px', padding: '1px'
}).click((e) => {
e.preventDefault();
d.remove();
}).appendTo(d);
$('<button/>').html(label).css({
fontSize: '14px'
}).click((e) => {
e.preventDefault();
d.remove();
this.init();
// w.history.pushState({a:location.href}, "* Супер-читалка", location.href);
}).appendTo(d);
if (!current) {
d.append('<div>Произойдет переход на стр. ' + this.init_wantPage + '</div>');
$('<button/>').html(
'Читать со страницы ' + this.init_comicsPage + ''
).css({
fontSize: '12px'
}).click((e) => {
e.preventDefault();
if (confirm(''
+ 'Вы собираетесь удалить закладку со страницы ' + this.init_wantPage
+ '\nи продолжить чтение со страницы ' + this.init_comicsPage
+ '\n\nВсё верно?'
)) {
this.wantPage = this.comicsPage = this.init_comicsPage;
// this.store();
// location.href = this.makeUrl(this.comicsPage);
d.remove();
this.init();
}
}).appendTo(d);
d.append('<div style="font-size:10px;">Закладка со стр. ' + this.init_wantPage + ' будет удалена.</div>');
}
d.css({
borderRadius: '4px',
position: 'fixed', // absolute
zIndex: 1e6,
right: '3px',
top: '3px',
padding: '4px',
background: 'rgba(0,0,0,0.6)',
color: '#fff',
border: '2px rgba(0,0,0,0.9) solid'
}).appendTo('body');
setTimeout(() => {
var inner = $('header.common > div.inner');
if (!inner.length) return;
if (d.offset().left < (inner.offset().left + inner.width() + 55)) {
d.css({ top: Math.round(inner.height() + 3) + 'px' });
}
}, 1);
}
}
var enableIntercept = false;
// disable built-in navigation with left/right arrow keys.
let _addEventListener = document.addEventListener;
document.addEventListener = function (en, fn, ...rest) {
if (en == 'keydown') {
let fnStr = fn?.toString();
if (fnStr.indexOf(`navElement.querySelector('a').getAttribute('href')`) !== -1) {
let origFn = fn;
fn = function (e) {
if (enableIntercept) return;
return origFn(e);
};
}
}
return _addEventListener.call(this, en, fn, ...rest);
};
class AcomicsViewerList2 {
static makeUrlReference(id, comicsName) {
return '/~' + comicsName + '/' + id;
};
initGuard = false;
init() {
if (this.initGuard) return;
this.initGuard = true;
if (!/\/-[A-Za-z0-9_-]+\/list2/.test(location.pathname)) { return; }
// $('div.contentSerialMargin > div.agrHolder >table.agr >tbody>tr:first-child>td.agrBody>div.numbers')
var div = $('div.agrHolder');
if (!div.length) { return; }
div.find('>table.agr').css({ marginBottom: '4px' }).each(function () {
// var a = $(this).find('>tbody>tr:first-child>td.agrBody>h3>a');
// if(!a.length){return;}
// a = a[0].pathname;
// if( a.substr(0,2)!='/~' ){return;}
// a=a.substr(2);
var b = $(this).find('>tbody>tr:first-child>td.agrBody>div.numbers a').eq(0);
if (!b.length) { return; }
b = b[0].pathname;
var m = /^\/~([^\/]+)\/(\d*)(?:\D|$)/.exec(b);
if (!m) { return; }
// parse page info
var comicsName = m[1];
var comicsPage = parseInt(m[2], 10);
if (m[2] == '' || isNaN(comicsPage) || comicsPage < 1) { return; }
var k = this.constants.localStorageKeyPrefix + comicsName; // stored shit
var stored = window.localStorage.getItem(k);
if (stored) { stored = parseInt(stored, 10) || false; } else { stored = false; }
if (!stored) { return; }
if (stored == comicsPage) {
$(this).css({ backgroundColor: '#ccc', outline: '1px #999 solid' });
} else if (stored < comicsPage) {
$(this).css({ backgroundColor: '#cff', outline: '1px #9ff solid' });
var link = $('<a/>').addClass('agr-today').attr(
'href', AcomicsViewerList2.makeUrlReference(stored, comicsName)
).text(
'Продолжить чтение со страницы ' + stored + ' (из ' + comicsPage + ')'
).css({
fontSize: '18px'
});
$(this).find('>tbody>tr:first-child>td.agrBody>div.numbers').prepend('<hr/>').prepend(link);
}
// this.comicsName = m[1];
// var comicsPage = parseInt(m[2],10);
});
}
}
$(function () {
(function () {
// $('.common .inner td.nainmenu > nav > a[href$="/list2"]').css({backgroundColor:'#f00'});
var a = $('.common .inner td.logo > a');
var img = a.find('> img');
if (!img.length) { return; }
var div = $('<div style="display:inline-block;overflow:hidden;width:55px;height:54px;height:100%;vertical-align:middle;padding-top:7px;" />');
img.detach();
div.append(img).appendTo(a);
$('.common .inner td.logo').css('width', 'auto');
var x = $('.common .inner td.nainmenu > nav > a[href$="/list2"]');
x.css({ fontWeight: 'bold' });
var y = $('<div/>').html('обновления').css({
display: 'inline-block', background: '#99f', borderRadius: '4px', border: '1px #66f solid',
position: 'absolute', marginTop: '-12px', marginLeft: '-48px',
width: '64px', height: '14px',
fontSize: '10px', fontFamily: 'sans-serif', textTransform: 'none', textAlign: 'center', fontWeight: 'normal'
});
y.insertBefore(x.find('>span'));
var live = $('.common .inner td.nainmenu > nav > a[href$="/live"]').contents().filter(function () { return this.nodeType === 3; }).eq(0);
if (live.length) { live[0].textContent = 'Live'; }
var Top = $('.common .inner td.nainmenu > nav > a[href$="//top.a-comics.ru/"]').contents().filter(function () { return this.nodeType === 3; }).eq(0);
if (Top.length) { Top[0].textContent = 'ТОП'; }
// window.lol_y = y;
// window.lol_x = x;
})();
let acomicsViewer = new AcomicsViewer();
if (!acomicsViewer.preInit()) {
let list2 = new AcomicsViewerList2();
list2.init();
return;
}
acomicsViewer.createRunInterface();
});
})();