// ==UserScript== // @name Image onMouseHover arch.b4k // @namespace Zero_G@4d7d460c-0424-11eb-adc1-0242ac120002 // @description Mouse over images to view full size // @include *://arch.b4k.co/*/thread/* // @version 1.4 // @grant none // @downloadURL none // ==/UserScript== (function(){ /** CONFIGURE SCRIPT **/ // Set this const to false if you don't want to change the place of the image file name. const changePlaceOfImageFilename = true; // Set max width for image-video container (in screen percentage) const maxWidth = '80%'; /** END CONFIGURE SCRIPT **/ // Variable to see if mouse is over image-video container // prevents triggering mouseout event when an image-video is over the thumbnail var onContainer = false; var savedId; // To store last triggered event id // Create image-video containers and append them var imageContainer = document.createElement('div'); var videoContainer = document.createElement('div'); var videoTag = document.createElement('video'); document.body.appendChild(imageContainer); document.body.appendChild(videoContainer); videoContainer.appendChild(videoTag); // Possition them a top right of current scroll imageContainer.style.position = 'fixed'; imageContainer.style.top = '0em'; imageContainer.style.right = '0em'; videoContainer.style.position = 'fixed'; videoContainer.style.top = '0em'; videoContainer.style.right = '0em'; // Hide containters imageContainer.style.visibility = 'hidden'; videoContainer.style.visibility = 'hidden'; // Prevent image-video from being bigger than screen imageContainer.style.height = '100%'; imageContainer.style.width = maxWidth; videoContainer.style.height = '100%'; videoContainer.style.width = maxWidth; videoTag.style.maxHeight = '100%'; videoTag.style.maxWidth = '100%'; // Wait for document to load $( document ).ready(function() { // Create event listeners const imageLinks = document.getElementsByClassName('thread_image_link'); Array.from(imageLinks).forEach(function(element) { element.addEventListener('mouseover', enlargeImage, false); // Hide image container element.addEventListener('mouseout', clear, false); }); // Change position of image name to atop of image thumb if(changePlaceOfImageFilename){ const imageNameList = document.getElementsByClassName('post_file'); Array.from(imageNameList).forEach(function(element) { let metadata = element.getElementsByClassName('post_file_metadata')[0]; if(metadata){ let filename = element.getElementsByClassName('post_file_filename')[0]; let div = document.createElement('div'); let span = document.createElement('span'); let wrapper = element.parentNode; div.className = 'post_file'; span.textContent = 'File: '; span.style.paddingLeft = '0.5em'; metadata.textContent = ' (' + metadata.textContent + ')'; metadata.style.fontSize = '85%'; div.appendChild(span); div.appendChild(filename); div.appendChild(metadata); wrapper.insertBefore(div, wrapper.getElementsByClassName('thread_image_box')[0]) element.innerHTML = element.innerHTML.replace(',', ''); } }); } // Attach mutation observers Array.from(postToObserve).forEach(function(element) { observer.observe(element, {childList: true, attributes: false, subtree: true}); }); }); function enlargeImage(event){ savedId = event.currentTarget.parentNode.parentNode.parentNode.id; if(/\.webm$/.test(event.currentTarget.href)){ // If it's a video if (videoTag.src !== event.currentTarget.href){ videoTag.src = ''; videoTag.src = event.currentTarget.href; } videoContainer.style.visibility = 'visible'; videoTag.play(); videoTag.loop = true; }else{ // If it's an image // Get post Id let id = event.currentTarget.parentNode.parentNode.parentNode.id; // Get image tag if exists let imgTag = imageContainer.querySelector('#i'+id); if(imgTag){ imgTag.style.display = 'block'; } else { imgTag = createImgTag(id, event.currentTarget.href); imageContainer.appendChild(imgTag); } imageContainer.style.visibility = 'visible'; } } imageContainer.addEventListener('mouseover', function() {onContainer = true;}); videoContainer.addEventListener('mouseover', function() {onContainer = true;}); imageContainer.addEventListener('mouseout', function() {onContainer = false; clear(null);}); videoContainer.addEventListener('mouseout', function() {onContainer = false; clear(null);}); function clear(event){ // Wait for image-videoContainer event mouseover // Timeouse loses event variable, so using savedId setTimeout(function(){ if(!onContainer){ imageContainer.style.visibility = 'hidden'; videoContainer.style.visibility = 'hidden'; // Hide imgTag let imgTag = imageContainer.querySelector('#i'+savedId); if(imgTag) imgTag.style.display = 'none'; // Stop video videoTag.pause(); videoTag.currentTime = 0; } }, 50); } function createImgTag(id, src){ var imgTag = document.createElement('img'); imgTag.style.maxHeight = '100%'; imgTag.style.maxWidth = '100%'; imgTag.style.display = 'block'; imgTag.id = 'i' + id; imgTag.src = src; return imgTag; } // Support for inline quotes (https://greasyfork.org/en/scripts/424112-inline-quote-links-arch-b4k-co) // Add mutation observers to all posts, then when an inline is detected add event listeners to image link var postToObserve = document.getElementsByClassName('text'); const observer = new MutationObserver(function(mutationsList, observer){ for(const mutation of mutationsList) { if(typeof(mutation.addedNodes[0]) != "undefined" && typeof(mutation.addedNodes[0].id) != "undefined"){ if(mutation.addedNodes[0].id.includes('inline')){ let imageLink = mutation.addedNodes[0].querySelector('.thread_image_link'); if (imageLink){ imageLink.addEventListener('mouseover', enlargeImage, false); imageLink.addEventListener('mouseout', clear, false); } } } } }); })()