Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // ==UserScript==
- // @name SadPandaScript
- // @namespace Rozenfag
- // @include https://exhentai.org/*
- // @match https://exhentai.org/*
- // @version 6
- // @author Aleksandr Petrov
- // @run-at document-end
- // @grant none
- // ==/UserScript==
- /*
- Здравствуй мой дорогой любитель фапа =3
- Для тебя (ну и конечно же для себя любимого), я накатал небольшой скрипт расширяющий функционал любимой грустнопанды.
- Для его запуска тебе понадобится современный браузер и расширение для выполнения UserScript-ов.
- Для Firefox это будет "Greasemonkey", для Opera нужно "Tampermonkey" или "Violent monkey", а для Chrome ищи "Trampermonkey".
- После установки нужного расширения, добавь в него этот скрипт и ты получишь следующие вкусности:
- 1) Возможность листать по пробелу. Очень удобно, особенно когда руки заняты, просто жмакнуть по большой конпке, а не целиться)))
- 2) Предзагрузка изображений, что позволяет избежать "морганий" при перелистывании контента. Незаменимая вещь на игровом арте, где зачастую фон не меняется, а меняются "эмоции" и появляются детали, вроде брызг спермы.
- 3) Слайдшоу режим, для полноценного освобождения рук)))))))))))))) Таймаут в секундах можете установить свой в переменной TIMEOUT_SEC_SLIDE_SHOW чуть ниже.
- 4) Автоматическое масштабирование изображения с помощью трех режимов: уменьшение до пределов окна, уменьшение или увеличение до пределов окна, и исходный размер.
- 5) Минимализм)) Только картинка и ты. Управление все через клавиши, т.к. как по мне это самое удобное. Кстати, очень круто в полноэкранном режиме браузера фапать))
- 6) Перевод на русский язык множества тегов, да еще и в виде крутой таблицы) Просто зайди на https://exhentai.org/ и нажми на "Показать список тегов" под поисковой формой. Очень удобно на лету выделить нужные фетиши, и сразу получить результат. А еще часть тегов автоматом переводится в галерее.
- [УПРАВЛЕНИЕ]
- ПРОБЕЛ или СТРЕЛОЧКА ВПРАВО: Следующая картинка.
- СТРЕРОЧКА ВЛЕВО: Предыдущая картинка.
- СТРЕЛОЧКА ВВЕРХ: Вернуться в галерею.
- СТРЕЛОЧКА ВНИЗ, F5: Обновить страницу, для получения настоящего URL, а не первого, т.н. "входного".
- TAB: Запуск и остановка слайдшоу.
- КЛИК ПО КАРТИНКЕ: Изменение режима масштабирования. Текущий можно посмотреть в значке вкладки.
- */
- var TIMEOUT_SEC_SLIDE_SHOW = 9; //По умолчанию картинка сменяется раз в 9 секунд.
- var GAY = false; //Гендер по умолчанию для тегов на главной. Если вы гетеро, ниечго не меняйте, если вы гей, смените на true
- var tag = {
- 'russian': ['lg', [0], 'Русский', 'Перевод на русский язык.'],
- 'english': ['lg', [0], 'Английский', 'Перевод на английский язык.'],
- 'translated': ['lg', [0], 'Перевод', 'Любой перевод с языка оригинала.'],
- 'age_progression': ['fm', [1], 'Увеличение возраста', 'Человек быстро становится старше.'],
- 'age_regression': ['fm', [1], 'Уменьшение возраста', 'Человек быстро становится моложе.'],
- 'dilf': ['ma', [1], 'Взрослый мужчина', 'Мужик в возрасте 30-50 лет.'],
- 'infantilism': ['fm', [1], 'Инфантилизм', 'Сексуальные действия, связанные с взрослым партнером, как если бы они были младенцем. Например, смена подгузника взрослому человеку..'],
- 'lolicon': ['fe', [1], 'Лоликон', 'Несовершеннолетние девушки с неразвитым телом в эротических ситуациях. Не следует путать с подростками или молодыми девушками.'],
- 'low_lolicon': ['fe', [1], 'Мягкий лоликон', 'Лоликон, не вписавшийся в правила ресурса.'],
- 'low_shotacon': ['ma', [1], 'Мягкий шотакон', 'Шотакон, не вписавшийся в правила ресурса.'],
- 'milf': ['fe', [1], 'Милфа', 'Женщина в возрасте 30-50 лет.'],
- 'old_lady': ['fe', [1], 'Старуха', 'Пожилая женщина за 50.'],
- 'old_man': ['ma', [1], 'Старик', 'Пожилой мужчина за 50.'],
- 'shotacon': ['ma', [1], 'Шотакон', 'Несовершеннолетние мальчики с неразвитым телом в эротических ситуациях. Не следует путать с подростками или молодыми парнями.'],
- 'toddlercon': ['fm', [1], 'Дети', 'Эротические сцены с детьми.'],
- 'amputee': ['fm', [2], 'Ампутации', 'У человека отсутствует одна или несколько конечностей. Может присутствовать гуро.'],
- 'body modification': ['fm', [2], 'Бодмод', 'Измененные части тела.'],
- 'conjoined': ['fe', [2], 'Сиамские близнецы', 'Две или более голов, из одного тела.'],
- 'doll_joints': ['fm', [2], 'Кукольные суставы', 'Шарнирные или похожие на них искуственные суставы.'],
- 'gijinka': ['fm', [2], 'Очеловечивание', 'Персонаж, не являющийся человеком, превращается или становится похож на него.'],
- 'inflation': ['fm', [2], 'Раздутие', 'Область живота неестественно выпуклая, словно надутый воздушный шарик. Часто, из-за заполнения газами/щупальцами/яйцами/жидкостями/существами и т.д.'],
- 'invisible': ['fm', [2], 'Невидимость', 'Совершение сексуальных действий, будучи невидимым.'],
- 'multiple_arms': ['fm', [2], 'Многорукость', 'Рук больше, чем две.'],
- 'multiple_breasts': ['fe', [2], 'Многогрудость', 'Грудей больше, чем две.'],
- 'multiple_nipples': ['fm', [2], 'Многососковость', 'Сосков больше чем обычно.'],
- 'multiple_penises': ['fm', [2], 'Мультипенисы', 'Обладание более чем одним пенисом.'],
- 'multiple_vaginas': ['fm', [2], 'Мультивагины', 'Обладание более чем одной вагиной.'],
- 'muscle': ['fm', [2], 'Мышцы', 'Мускулистое телосложение.'],
- 'muscle_growth': ['fm', [2], 'Мышечный рост', 'Мышцы увеличиваются в размерах или появляются там, где их небыло.'],
- 'pregnant': ['fm', [2], 'Беременность', 'Сексуальные действия с беременным человеком.'],
- 'stretching': ['fm', [2], 'Растяжение', 'Растяжение частей тела за пределами человеческих возможностей.'],
- 'tailjob': ['fm', [2], 'Хвост', 'Использование хвоста, чтобы стимулировать половые органы.'],
- 'wings': ['fm', [2], 'Крылья', 'На теле присутствуют крылья.'],
- 'absorption': ['fm', [3], 'Поглощение', ''],
- };
- // 'aaaaaa': ['fm', [], 'bbbbbb', ''],
- var fetCat = [
- 'язык', // 0
- 'возраст', // 1
- 'тело', // 2
- 'изменения' // 3
- ];
- var catTag = {
- 'fe': ['female', 'женское'],
- 'ma': ['male', 'мужское'],
- 'fm': [(GAY===false?'female':'male'), (GAY===false?'женское':'мужское')],
- 'lg': ['language', 'язык'],
- 'ms': ['misc', 'разное']
- };
- window.addEventListener('load', function(){
- var regexpMain = /^https:\/\/exhentai\.org\/?[^\.\/]*$/; //Главная
- var regexpGallery = /^https:\/\/exhentai\.org\/g\/\d+\/[\d\w]+\/.*$/; //Галерея
- var regexpImage = /^https:\/\/exhentai\.org\/s\/[\d\w]+\/[\d\-]+$/; //Изображение
- //-----------------------------------------------------------------------------------------------------
- if(regexpMain.test(document.location.toString())){ // [Создание таблицы тегов на главной]
- //-----------------------------------------------------------------------------------------------------
- var show = false; var fetID=[];
- var space = document.createTextNode(' \u00A0\u00A0');
- var tagDivCont = document.createElement('div');
- var showHideTag = document.createElement('a');
- var advdiv=document.getElementById('advdiv');
- Element.prototype.addCategory = function(text) {
- var tr = document.createElement('tr');
- var td1= document.createElement('td');
- var td2 = document.createElement('td');
- td1.className = 'tc';
- td1.innerHTML = text;
- tr.appendChild(td1);
- tr.appendChild(td2);
- this.appendChild(tr);
- return td2;
- };
- Element.prototype.addTag = function(tagname) {
- var div = document.createElement('div');
- var a = document.createElement('a');
- var tagid = tag[tagname];
- div.className = 'gt';
- a.innerHTML = tagid[2];
- a.title = tagid[3];
- a.href = '#';
- a.id = tagname;
- div.appendChild(a);
- this.appendChild(div);
- };
- function changeTag(t){
- var inpSearch = document.getElementsByName('f_search')[0];
- var query = catTag[tag[t][0]][0]+':'+t;
- var pos = inpSearch.value.indexOf(query);
- if(pos<0){
- inpSearch.value += (inpSearch.value.length>0?' ':'') + query;
- return true;
- }else{
- inpSearch.value = inpSearch.value.replace((pos===0?'':' ') + query + (pos===0?(inpSearch.value.length==query.length?'':' '):''), '');
- return false;
- }
- }
- showHideTag.innerHTML = 'Показать список тегов';
- showHideTag.href = '#';
- advdiv.previousSibling.appendChild(space);
- advdiv.previousSibling.appendChild(showHideTag);
- showHideTag.addEventListener ('click', function(){
- if(show === true){
- showHideTag.innerHTML = 'Показать список тегов';
- tagDivCont.style.display='none';
- }else{
- showHideTag.innerHTML = 'Скрыть список тегов';
- tagDivCont.style.display="";
- }
- show = !show;
- }, false);
- var toppane=document.getElementById('toppane');
- tagDivCont.className = 'idi';
- tagDivCont.style.display='none';
- toppane.appendChild(tagDivCont);
- var tagDiv = document.createElement('div');
- var tagTable = document.createElement('table');
- var tagTbody = document.createElement('tbody');
- tagDiv.id = 'taglist';
- tagDiv.style.height = 'auto';
- tagDivCont.appendChild(tagDiv);
- tagDiv.appendChild(tagTable);
- tagTable.appendChild(tagTbody);
- for(var f=0; f<fetCat.length; f++){
- fetID[f] = tagTbody.addCategory(fetCat[f]);
- }
- for (var key in tag) {
- fetID[tag[key][1]].addTag(key);
- }
- var inpSearch = document.getElementsByName('f_search')[0];
- if(inpSearch.value.length>0){
- var tags = inpSearch.value.split(' ');
- tags.forEach(function(item) {
- var ptag = item.split(':');
- if ((ptag.length>0)&&(typeof tag[ptag[1]] !== 'undefined')) {
- var ttag = document.getElementById(ptag[1]);
- if(typeof ttag !== 'undefined') ttag.style.color = 'blue';
- }
- });
- showHideTag.click();
- }
- tagTable.addEventListener ('click', function(e){
- if(e.target.tagName == 'A') e.target.style.color = (changeTag(e.target.id) === true?'blue':'');
- }, false);
- //-----------------------------------------------------------------------------------------------------
- }else if(regexpGallery.test(document.location.toString())){ // [Перевод тегов галерее]
- //-----------------------------------------------------------------------------------------------------
- var taglist = document.getElementById('taglist').getElementsByTagName('tr');
- if(taglist.length>0){
- for(var i=0; i<taglist.length; i++){
- var trTag = taglist[i].firstChild.innerHTML.substring(0,taglist[i].firstChild.innerHTML.length-1);
- for (var j in catTag) {
- if(catTag[j][0] == trTag){
- var aList = taglist[i].lastChild.getElementsByTagName('a');
- for(var k=0; k<aList.length; k++){
- var atag = aList[k].id.toString().substr(4+trTag.length);
- if(typeof tag[atag] !== 'undefined'){
- aList[k].innerHTML = tag[atag][2];
- aList[k].title = tag[atag][3];
- }
- }
- taglist[i].firstChild.innerHTML = catTag[j][1];
- break;
- }
- }
- }
- }
- //--------------------------------------------------------------------------------------------------------
- }else if(regexpImage.test(document.location.toString())){ // [Прокачка режима просмотра изображений]
- //--------------------------------------------------------------------------------------------------------
- //Всякие переменные и картинки в base64 формате.
- var gallURL = document.getElementById('i5').getElementsByTagName('a')[0].href;
- var currURL, nextURL, prevURL;
- var block = false, blockIMG = false;
- var timer;
- var timeoutURL, timeoutIMG;
- var ScaleMode = 1;
- var slideShow = false;
- var loadIMG, showIMG;
- var loadImgW, loadImgH, showImgW, showImgH;
- var timeout_LoadIMG = 14000; //Таймаут в мс, на загрузку изображения.
- var favicons = [
- 'data:image/gif;base64,R0lGODlhEAAQAMIGAGYGEYCAgJmZmbOzs8zMzOXl5f///////yH/C05FVFNDQVBFMi4wAwEAAAAh+QQFCgAHACwAAAAAEAAQAAADNAi63HowSvmmhfXOrCPvx9eJGnk9jhMCYVEQxDAIQhCwqAvLtI3jutisdlutUgsjyINEJgAAIfkEBQoABwAsAwAKAAoAAwAAAw1IVKUzQijmoFyNvJgAACH5BAUKAAcALAMACgAKAAMAAAMLOENUxUoxB+N8RCUAIfkEBQoABwAsAwAKAAoAAwAAAw0oMkNUxSnmoFztRZIAACH5BAUKAAcALAMACgAKAAMAAAMNGCEyQ6QUxRyUtL1YEgAh+QQFCgAHACwDAAoACgADAAADDSgSoTOEKOagXE28mAAAIfkEBQoABwAsAwAKAAoAAwAAAws4IxLBSjEH43xCJQAh+QQBCgAHACwDAAoACgADAAADDUg0IxLBKeagXO1FkQAAOw==',
- 'data:image/gif;base64,R0lGODlhEAAQAIABAGYGEf///yH5BAEKAAEALAAAAAAQABAAAAIohI9pwe2+nmRxvmobzmFnb4FThFCHCQGoplKd23bt7L6yHd4cq/RGAQA7',
- 'data:image/gif;base64,R0lGODlhEAAQAIABAGYGEf///yH5BAEKAAEALAAAAAAQABAAAAIthI9pwe2+EDwhgtds3e96z1xZWIkjl5lYp65pR06cKn5be5f6qkmp5mIphoYCADs=',
- 'data:image/gif;base64,R0lGODlhEAAQAIABAGYGEf///yH5BAEKAAEALAAAAAAQABAAAAIghI9pwe2+nmRxvmobzmFnb4GTKJEXwEFoSq2sqSqyUQAAOw=='
- ];
- //Удаляем все ненужное со страницы
- window.onpopstate = null;
- window.onresize = null;
- window.onload = null;
- document.onkeydown = null;
- document.body.innerHTML = "";
- document.body.style.textAlign = 'center';
- document.body.style.padding = '0px';
- //Создаем два пустых изображения. Первое сделаем скрытым от глаз, и будем в него грузить нужную картинку, а после загрузки, без всяких морганий,
- //перекинем во второе, которое видимо. Кароче, в одном все грузится, во втором показывается.
- loadIMG = document.createElement("img");
- showIMG = document.createElement("img");
- document.body.appendChild(loadIMG);
- document.body.appendChild(showIMG);
- loadIMG.style.width = '0px';
- loadIMG.style.height = '0px';
- showIMG.style.cursor = 'pointer';
- //Функция для показа анимации загрузки вместо стандартного значка грустнопанды во вкладке, чтоб было видно, что чет грузится.
- function changeFavicon(mode){
- var head = document.head || document.getElementsByTagName('head')[0];
- var link = document.createElement('link');
- link.id = 'dynamic-favicon';
- link.rel = 'shortcut icon';
- link.href = favicons[(mode<0?ScaleMode:mode)];
- var oldLink = document.getElementById('dynamic-favicon');
- if(oldLink) head.removeChild(oldLink);
- head.appendChild(link);
- }
- //Обрабатываем событие окончания загрузки нашей картинки в скрытом от глаз изображении.
- loadIMG.addEventListener ('load', function(){
- blockIMG = true;
- clearTimeout(timeoutIMG); //Удаляем таймаут на загрузку пикчи, а то вылезет попап, что мы якобы еще её грузим.
- showImgW = loadImgW;
- showImgH = loadImgH;
- ScaleImage();
- showIMG.src = loadIMG.src;
- changeFavicon(-1);
- block = false;
- blockIMG = false;
- window.scrollTo(0,0);
- }, false);
- //Функция для изменения размеров картинки в зависимости от режима маштабирования.
- function ScaleImage(){
- var ratio = Math.min((window.innerWidth-2) / showImgW, (window.innerHeight-2) / showImgH);
- if( ((ScaleMode == 1) && (ratio >= 1)) || (ScaleMode == 3) ) ratio = 1;
- showIMG.style.width = parseInt(showImgW*ratio)+'px';
- showIMG.style.height = parseInt(showImgH*ratio)+'px';
- }
- //Обрабатываем клик по изображению. Это меняет режим масштабирования.
- showIMG.addEventListener ('click', function(){
- ScaleMode = (ScaleMode==3?1:ScaleMode+1);
- if(blockIMG === false) ScaleImage();
- if(block === false) changeFavicon(ScaleMode);
- }, false);
- //Эта функция грузит нужную страницу в галерее и получает все данные о изображении на ней.
- function getImage(url){
- if(block === false){ //Если заблочено, значит что-то грузится и делать ничо не будем)
- if(url === currURL){ //На случай окончания картинок в галерее. Просто выходим в ее корень, с превьюхами.
- slideShow=false;
- document.location = gallURL;
- }else{ //Все ОК можно грузить страницу.
- block = true; //Блочим функцию на период ее асинхронного выполнения.
- changeFavicon(0); //Анимируем значок во вкладке.
- var xmlhttp = new XMLHttpRequest();
- xmlhttp.open('GET', url, true); //Формируем запрос на грустнопанду.
- //Обрабатываем событие прихода ответа.
- xmlhttp.onreadystatechange=function(){
- if(xmlhttp.readyState != 4) return;
- clearTimeout(timeoutURL); //Ответ пришел, можно удалять таймаут на него.
- if(xmlhttp.status == 200){ //Ответ пришел какой мы и ждали)
- //Тут мы долго и скучно вытаскиваем из пришедшего html кода адреса для навигации, размер картинки и т.д.
- var tempDOM = new DOMParser().parseFromString(xmlhttp.responseText, "text/xml");
- nextURL=tempDOM.getElementById("next").href;
- prevURL=tempDOM.getElementById("prev").href;
- currURL=url;
- var imageSize = tempDOM.getElementById("i2").childNodes[1].innerHTML.split(' :: ')[1].split(' x ');
- loadImgW = imageSize[0];
- loadImgH = imageSize[1];
- //Начинаем грузить картинку в скрытое изображение по полученному адресу из ответа.
- loadIMG.src = tempDOM.getElementById("img").src;
- //Таймаут на загрузку картинки, т.к. грустнопанда не отличается идеальной стабильностью.
- timeoutIMG = setTimeout( function(){
- alert('ОШИБКА: Загрузка изображения длилась более '+parseInt(timeout_LoadIMG/2000)+' сек. и была прервана.');
- changeFavicon(-1);
- block = false;
- }, 100+parseInt(timeout_LoadIMG/2));
- } else {//Все ужасно(((
- alert('ОШИБКА: При загрузке exhentai.org возникли неполадки. Подробнее: ' + xmlhttp.statusText);
- }
- };
- xmlhttp.send(null); //Отправляем запрос на грутснопанду.
- //Таймаут запроса, на случай подвисшего инета, глюков на грустнопанде и прочих сетевых неврозах.
- timeoutURL = setTimeout( function(){
- xmlhttp.abort();
- alert('ОШИБКА: Загрузка exhentai.org длилась более '+parseInt(timeout_LoadIMG/2000)+' сек. и была прервана.');
- changeFavicon(-1);
- block = false;
- }, 100+parseInt(timeout_LoadIMG/2));
- }
- }
- }
- //Обрабатываем нажатие клавиш.
- document.body.addEventListener ('keydown', function(event){
- switch(event.keyCode){
- case 9://TAB
- slideShow = (slideShow===false?true:false);
- if(slideShow===true){
- alert('СЛАЙДШОУ: Запущена смена изображений раз в '+TIMEOUT_SEC_SLIDE_SHOW+' сек.');
- timer = setInterval(function(){
- if(slideShow===false){
- clearInterval(timer);
- }else{
- getImage(nextURL);
- }
- }, TIMEOUT_SEC_SLIDE_SHOW*1000);
- }else{
- alert('СЛАЙДШОУ: Остановлено.');
- }
- break;
- case 32://ПРОБЕЛ
- case 39://СТРЕЛОЧКА ВПРАВО
- getImage(nextURL); //Следущее изображение.
- break;
- case 37://СТРЕЛОЧКА ВЛЕВО
- getImage(prevURL); //Предыдущее изображение.
- break;
- case 38://СТРЕЛОЧКА ВВЕРХ
- document.location = gallURL; //Возвращение в галерею с превьюшками.
- break;
- case 40://СТРЕЛОЧКА ВНИЗ
- case 116://F5
- event.preventDefault();
- document.location = currURL; //Рефрешнуть страницу. Полезно для получения правильной ссылки на страницу в адресной строке.
- break;
- }
- }, false);
- getImage(document.URL); //Загружаем картинку начальной страницы, ведь мы удалили все в теге <body> очистив от всего лишнего.
- }
- }, false);
Add Comment
Please, Sign In to add comment