// ==UserScript==
// @name ModalImg en rule34
// @namespace http://tampermonkey.net/
// @version 3.0
// @description Te crea una galería dentro de los post ;D. Agrega zoom e infinity scroll
// @author falaz
// @match http*://rule34.xxx/index.php?page=post&s=list*
// @grant none
// ==/UserScript==
/*jshint esversion: 6 */
const css =`<style>
#blackCoso{
width: 100%;
background-color: rgb(0,0,0,0.5);
position: fixed;
height: 100%;
z-index: 999999;
display:none;
transition: display 2s;
}
#closeContainer{
background-color: rgb(0,0,0,0.6);
color: white;width: 48px;height: 48px;
border-radius: 24px;cursor: pointer;
text-align: center;margin-right: 10px;font-size: 34px;margin-left: auto;margin-top: 10px;
}
#currentImg,#currentWeb{
height: 100%;
max-height: calc(937px - 140px);
width: auto;
padding: 70px;
position: fixed;
display: none;
margin: 0;
top: 50%;
left: 50%;
margin-right: -50%;
transform: translate(-50%, -50%);
}
#closeModal:hover {
color: red;
}
</style>`;
const modal = `
<div id="closeContainer"><a id="closeModal">X</a><div></div></div>
<img id="currentImg" src="">
<video id="currentWeb" loop autoplay controls>
<source src="" type="video/webm">
</video>`;
let liSelect = `<label>Show only: </label><select id="typeSelector"><option name="all">All
</option><option name="video">video</option><option name="video">images</option></select>`;
/* Credits to Sam https://twitter.com/sherb */
const loadingSVG = "https://samherbert.net/svg-loaders/svg-loaders/puff.svg";
const padre = document.createElement('div');
let liSelector = document.createElement('li');
window.images = [];
window.imagesObj = [];
let infinitySended = false;
let next = document.querySelector('a[alt="next"]');
let paginator = document.querySelector('#paginator');
let subnav = document.querySelector('#subnavbar');
let filter = 0; // 0= all, 1= video/gif, 2= images
let filters = [{'filter':['']},{'filter':['webm', 'gif', 'animated']},{'filter':['']}];
const dp = new DOMParser();
(function() {
padre.id = "blackCoso";
padre.innerHTML = modal + css;
padre.dataset.position = 0;
liSelector.innerHTML = liSelect;
var header = document.querySelector('#header');
subnav.appendChild(liSelector);
document.body.appendChild(padre);
document.body.insertBefore(padre,document.body.firstChild);
var currentImg = document.querySelector('#currentImg');
var blackCoso = document.querySelector('#blackCoso');
var typeSelector = document.querySelector('#typeSelector');
currentImg.dataset.zoomed = 'false';
var imgContainer = document.querySelector('.content div:first-of-type');
addModalToImages(imgContainer);
var closeModal = document.querySelector('#closeModal');
typeSelector.addEventListener('change',()=>{filterPost(typeSelector.value);});
closeModal.addEventListener('click',()=>{blackCoso.style.display = 'none';currentWeb.pause();zoomed(false);});
blackCoso.addEventListener('click',()=>{blackCoso.style.display = 'none';currentWeb.pause();zoomed(false);});
currentWeb.addEventListener('click',(e)=>{e.target.pause();});
document.addEventListener('keyup',(e)=>{
if(blackCoso.style.display == 'flex' && (e.code == 'ArrowRight' || e.code == 'ArrowLeft')){
var current = Object.keys(window.images).indexOf(blackCoso.dataset.position);
var direction = e.code == 'ArrowRight'? 1: -1;
if(current >= window.images.length || current < 0){
showModal(Object.keys(window.images)[0]);
if(current >= window.images.lenght - 1){
infinityScroll();
}
}else{
// window.images = filterPostOnImage(filter == 1?'video':'images', window.imagesObj);
showModal(Object.keys(window.images)[current+ direction]);
}
}
});
/*Add zoom when click the image*/
currentImg.addEventListener('click',e=>{
e.stopPropagation();
zoomed();
});
/* Move the zoomed Image*/
currentImg.addEventListener('mousemove',e=>{
if(currentImg.dataset.zoomed == 'true'){
//console.log({w:currentImg.offsetWidth,iw:window.innerWidth});
var calcX = currentImg.getBoundingClientRect().width>window.innerWidth?(e.clientX/2 - (currentImg.width/2 -20)) +'px,':'-20px,';
var calcY = currentImg.offsetHeight>=window.innerHeight?(e.clientY - (currentImg.height/2+30)) +'px':'0px';
//console.log({calcX,calcY});
currentImg.style.transform = 'scale(5.5) translate(' + calcX + calcY + ')';
}
});
/*Inifinity Scroll*/
paginator.style.display= 'none';
window.addEventListener('scroll',(e)=>{
if(scrollY>=paginator.getBoundingClientRect().top - 100 && !infinitySended ){
infinityScroll();
}
});
document.querySelector('.horizontalFlexWithMargins').remove();
})();
var regxImg = /(?<=src=")(.*)(?=("\s*id="image"))/gm;
var regxWebM= /(?<=source src=")(.*)(?="\stype\=\"video\/webm\")/gm;
function showModal(position=0){
blackCoso.style.display = 'flex';
padre.dataset.position = position;
currentWeb.pause();
if(!window.images[position]){
console.log('break');
}
imageExists(window.images[position].url).then((resp)=>{
if(resp.type=='img'){
currentWeb.style.display='none';
currentImg.style.display='block';
currentImg.src = resp.content;
}else{
currentWeb.style.display='block';
currentImg.style.display='none';
currentWeb.children[0].src = resp.content;
currentWeb.load();
currentWeb.play();
}
}).catch((reject)=>{
console.log('no existe D:');
});
currentImg.src = loadingSVG;
}
function imageExists(image_url){
return new Promise((result, reject)=>{
var http = new XMLHttpRequest();
http.open('GET', image_url);
http.onload = ()=>{
if (http.status === 200){
let documentImage = http.response;
let b = dp.parseFromString(documentImage, 'text/html');
let meta = b.querySelector('meta[itemprop="image"]');
if(meta){
if(/\.mp4|\.webm|\.gif/.test(meta.content)){
result({type:'webm',content: meta.content});
}else{
result({type:'img', content: meta.content});
}
}else{
reject('null');
}
}
};
http.send();
});
}
function infinityScroll(){
console.log('reach');
infinitySended = true;
if(next){
fetch(next.href).then(response=>{return response.text();})
.then(text=>{
var domP = new DOMParser();
var documentNext = domP.parseFromString(text,'text/html');
next = documentNext.querySelector('a[alt="next"]');
var contentViews = documentNext.querySelector('.content div:first-of-type');
addModalToImages(contentViews);
document.querySelector('.content').insertBefore(contentViews, paginator);
infinitySended = false;
filterPost('');
});
}
}
function addModalToImages(imgArray){
// console.log(imgArray)
Array.from(imgArray.children).forEach((e,i)=>{
//console.log(e);
e.childElements().forEach(child=>{child.addEventListener('click',(event)=>{
event.preventDefault();
showModal(e.id);
});});
//images.push(e.children[0].children[0].src);
window.images[e.id] = {url:(e.children[0].href),type: determineType(e)};
window.imagesObj[e.id] = {url:(e.children[0].href),type: determineType(e)};
});
}
function determineType(spanNode){
if(spanNode.querySelector('img').alt.includes('video')){
return 'video';
}else if(spanNode.querySelector('img').alt.includes('gif')){
return 'gif';
}else{
return 'image';
}
}
function filterPostOnImage(word, images){
let b = {};
for (const key in images) {
if (Object.hasOwnProperty.call(images, key)) {
const element = images[key];
if(element.type== word){
b[key] = element;
}
}
}
return b;
}
function filterPost(word=''){
if(word!=''){
switch(word){
case 'all':
case 'All':
filter = 0;break;
case 'video':
filter = 1;break;
case 'images':
filter = 2;break;
}
}
document.querySelectorAll('.content span').forEach(function(e){
var displayed = false;
var alt = e.querySelector('img').alt;
// console.log(filters);
for(var i=0;i<filters[filter].filter.length;i++){
if(alt.includes(filters[filter].filter[i])){
displayed= true;
}
}
e.style.display= displayed?'block':'none';
});
if(filter != 0){
window.images = filterPostOnImage(filter==1?'video':'image', window.imagesObj);
}
}
function zoomed(zoomed = -1){
// console.log(currentImg.dataset.zoomed);
if(zoomed == -1 && currentImg.dataset.zoomed == 'false'){
currentImg.style.transform = 'scale(5.5) translate(-20px, 230px)';
currentImg.dataset.zoomed = 'true';
currentImg.style.maxHeight= 'none';
}else{
currentImg.style.transform = '';
currentImg.style.maxHeight= '';
currentImg.dataset.zoomed = 'false';
}
}