// ==UserScript==
// @name cats webcomic tool
// @description initial scrolling and a hotkey
// @namespace gnblizz
// @include http://*
// @noframes
// @version 2.01
// @icon data:image/gif;base64,R0lGODdhIAAgAMIGAAAAACsrK1VVVYCAgKqqqtTU1P///////ywAAAAAIAAgAAAD/mi63P4wyhmFGKPQrcIwxSAQ3HRpioiWzrkUBMkWrjHEL5Hlq0PrFkzoRbMEAJ7dQ1BownQEprN4ITSZD0wjCoVdR87op/UI3VLmy4gQ8IAWOEbzNjTEMgOP+a0UbDEyfiBaP1EXGFh1KTorYzYfMCNrMVhxjzYwRwAoFyA6Qk1RaCmQH3cWTQEkZqqhI6N1SqGrACSGTJSOY6+YDDhsp09iDKa8ip4GFjoAN0AyCx8BdZaDyZIWQT2kJGM0KyFFA0htWA5RGjuRL4htAWDn5oJDzUFq7QJ6kRhKogrD0IgAAMB2CEMrBoL8JbRhaKAaGPu02YnwxJ20KKpYeLKCMEeNghA1KJxj88EPMDkcvBVw18SfRT0lpLj5KG6ShZQ3YC5A9dHbBkNnBvFc96xBAgA7
// @grant GM_registerMenuCommand
// @grant GM_xmlhttpRequest
// ==/UserScript==
"use strict";
var HotKey = 'ArrowRight'; // You can customize the hotkey here.
try { GM_registerMenuCommand('configure Cats Webcomic Tool', CatsConfig, 'w'); } catch(e){
console.log('couldn\'t add menu.');
}
try { if(document.domain=='www.egscomics.com') { if(document.getElementById('newsarea').textContent.match(/^No DVD movie style commentary/))
document.getElementById('news').textContent = 'No comments';
document.getElementById('leftarea').removeChild(document.getElementById('boxad'));
document.getElementById('leftarea').removeChild(document.getElementById('ibar'));
}} catch(e){}
(function Cats2(d) {
if(d) {
d = d.split('|');
Set(parseInt(d[0]), parseInt(d[1]), decodeURIComponent(d[2]));
}
}(GetCookie('CatsWebcomicTool')));
/* Set function:
* x int, optional amount of pixels to scroll right
* y int amount of pixels to scroll down
* name string identifier of the next button (see FindLink function)
* style string, optional css style string to apply
* return boolean success */
function Set(x, y, name, style) {
if(!FindLink(name)) {
console.log('CatsWebcomicTool: "'+name+'" not found at '+document.domain);
return false;
}
document.body.style.minHeight = (y + window.outerHeight) + 'px';
if(window.scrollY < y)
window.scroll(x, y);
if(obj('#us_MiniClock')) obj('#us_MiniClock').style.opacity='.2';//test
if(name != '/') document.body.onkeypress=function(event) {
if(event.key == HotKey) {
var l = FindLink(name);
if(l) {
if(l.nodeName == 'LINK')
window.location.assign(l.getAttribute('href'));
else
l.click();
event.preventDefault();
}
}
};
return true;
}
/* GetLinkAdr function:
* node object the next button
* return text URL next page */
function GetLinkAdr(o) {
if(!o) return;
var x = o.getAttribute('href');
if(x) return x;
x = o.querySelector('*[href]');
if(x) return x.getAttribute('href');
do {
o = o.parentNode;
switch(o.nodeName) { case 'BODY': case 'HTML': return; }
x = o.getAttribute('href');
} while(!x);
return x;
}
/* FindLink function:
* name string identifier of the next button
* return object next button
identifier format:
! the head contains a link with rel="next" attribute
* the link has a rel="next" attribute
#name name is an id tag
.name name is a class id
/name name is part of a path to an image
$name name is the textContent of a link */
function FindLink(name) {
var i, o, l;
switch(name.charAt(0)) {
case '#':
case '.':
return obj(name);
case '!':
return document.head.querySelector('link[rel="next"][href]');
case '$':
name = decodeURIComponent(name.slice(1));
o = document.links;
i = o.length;
if(i) do {
l = o[--i];
if(l.textContent == name) {
return l;
}
} while(i);
return null;
case '*':
return document.body.querySelector('a[rel="next"]');
case '/':
o = document.images;
i = o.length;
if(i) do {
l = o[--i];
if(('/'+l.getAttribute('src')).search(name) >= 0)
return l;
} while(i);
return null;
case '?': // new, undok
return document.body.querySelector('a[title="'+name.slice(1)+'"]');
default:
throw('Undefined string type in FindLink('+name+')');
}
return null;
}
function obj(str){var node = null;switch (str.charAt(0)){case '#':node=document.getElementById(str.slice(1));break;case '.':node=document.getElementsByClassName(str.slice(1))[0];break;case '+':node=document.createElement(str.slice(1).toUpperCase());break;default:node=document.getElementsByTagName(str)[0];break;}return node;}
function parent(path) { path = path.match(/^(.*)\/[^/]+\/?$/); return (path && path[1]) ? path[1] : '/'; }
function SetCookie(name, value, days, path) {
if(!path) path='/';
var d = new Date();
d.setTime(days*86400000+d.getTime());
document.cookie=name+'='+value+';expires='+ d.toUTCString()+';'+'path='+path;
}
function GetCookie(name) {
var r = new RegExp(name+'=([^;]+)', '')
var m = document.cookie.match(r);
return(m ? m[1] : '');
}
function BiggestImage() {
var a=document.images, i, img, biggestSize=0;
if(!a || !(i=a.length)) { alert('No image found.'); return null; }
do {
var o = a[--i], size=o.offsetWidth*o.offsetHeight;
if(size>biggestSize) { biggestSize=size; img=o; }
} while(i);
return img;
}
function CatsConfig() {
try {
var ctrl = obj('#CatsWebcomicTool'); if(ctrl) ctrl.parentNode.removeChild(ctrl);
var img=BiggestImage(),rect=img.getBoundingClientRect(),cwctX=parseInt(rect.left+window.scrollX),cwctY=parseInt(rect.top+window.scrollY),cwctKey,key2,path,
akey='!|*|.comic-nav-next|.next|.navi-next|.arrow_next|.comic-nav-next|/next|/arrow_next|/next_day|/next button|/nnxt|/foward|/Nav_ForwardOne|/NavigationNext|/arrow_nexttop|#next|#cndnextt|$next|$Next|$Next >|$Next Page|?next|?Next|$%20%C2%A0next%C2%A0%3E%C2%A0%20|/'.split('|');
while(cwctKey=key2=akey.shift()) {
if(cwctKey.charAt(0) == '/') { if(FindLink(cwctKey+='.gif')) break; if(FindLink(cwctKey=key2+'.png')) break; cwctKey=key2+'.jpg'; }
if(FindLink(cwctKey)) break;
}
window.scroll(cwctX, cwctY);
confirm();
} catch(e) {
console.log(e);
}
function confirm() {
var frm = obj('+FORM'), style = obj('+STYLE'), opt, sel = 0;
frm.id = 'CatsWebcomicTool';
addCtrl('x', cwctX, 'set this to "0", if page centers horizontally');
ctrl.onchange = function() { window.scroll(cwctX = parseInt(this.value), cwctY); }
addCtrl('y', cwctY, 'vertical offset');
ctrl.onchange = function() { window.scroll(cwctX, cwctY = parseInt(this.value)); }
addCtrl('next', cwctKey, 'identifier for the next button\n\n!\tthe page head contains a link with rel="next" attribute\n*\tthe link has a rel="next" attribute\n#name\tname is an id tag\n.name\tname is a class id\n/name\tname is part of a path to an image\n$name\tname is the textContent of a link\n\nif unsure type in "/", which disables the hotkey.');
ctrl.onchange = function() { ctrl.title = (/^([!*/]|[#./$].+)$/.test(cwctKey = this.value) && FindLink(cwctKey)) ? 'store settings and close this bar' : 'discard settings and close this bar'; }
if(!(path = location.pathname)) path = '/';
if(path != '/') {
addCtrl('path', [], 'select the part of the URL, which is common to all pages\nif unsure, select "/"');
if(path.slice(-1) == '/') {
sel++;
ctrl.add(opt = obj('+OPTION'));
opt.innerHTML = path = path.slice(0,-1);
} else if(/\d[^/]*$/.test(parent(path))) sel++;
do {
ctrl.add(opt = obj('+OPTION'));
opt.text = path = parent(path);
} while(path.length > 1);
ctrl.selectedIndex = sel;
path = ctrl.value;
ctrl.onchange = function() { if(GetCookie('CatsWebcomicTool')) SetCookie('CatsWebcomicTool', '', -1, path); path = this.value; }
}
addCtrl(' OK ', undefined, 'store settings and close this bar');
ctrl.onclick = function() {
try {
if(cwctKey) {
SetCookie('CatsWebcomicTool', cwctX + '|' + cwctY + '|' + encodeURIComponent(cwctKey), 182, path); // 182 = half a year
Set(cwctX, cwctY, cwctKey);
} else
SetCookie('CatsWebcomicTool', '', -1, path);
} catch(e){}
document.body.removeChild(this.parentNode);
};
style.innerHTML = 'form#CatsWebcomicTool{z-index:2147483647;position:fixed;left:0px;right:0px;bottom:0px;margin:0px;padding:2px;color:white;background-color:gray;}form#CatsWebcomicTool label{display:inline}form#CatsWebcomicTool input,form#CatsWebcomicTool select{display:inline;width:unset;margin-right:7px;}form#CatsWebcomicTool input[type="number"]{width:45px;text-align:end;}';
frm.appendChild(style);
document.body.appendChild(frm);
function addCtrl(name, value, title) {
var lbl;
ctrl = obj((name!='path') ? '+INPUT' : '+SELECT');
switch(typeof(value)) {
case 'undefined':
ctrl.setAttribute('type', 'button');
ctrl.setAttribute('value', name);
break;
case 'number':
ctrl.setAttribute('type', 'number');
ctrl.setAttribute('min', '0');
default:
lbl = obj('+LABEL');
lbl.setAttribute('for', name);
lbl.innerHTML = name+':';
frm.appendChild(lbl);
ctrl.setAttribute('name', name);
if(value) ctrl.setAttribute('value', value);
}
ctrl.id = name;
ctrl.title = title;
frm.appendChild(ctrl);
return ctrl;
}}}
// public domain by gnblizz
// contact me with my username + '@web.de'