// ==UserScript==
// @name 1337x - UX Enhancement
// @namespace http://tampermonkey.net/
// @version 1.4
// @description Extend titles, add images to torrent list, full width site
// @author French Bond
// @match https://1337x.to/*
// @grant GM_xmlhttpRequest
// @grant GM_addStyle
// @license MIT
// @downloadURL https://update.greasyfork.icu/scripts/479974/1337x%20-%20UX%20Enhancement.user.js
// @updateURL https://update.greasyfork.icu/scripts/479974/1337x%20-%20UX%20Enhancement.meta.js
// ==/UserScript==
const VISIBLE_IMAGES = 4; // Number of images to show initially
(function () {
'use strict';
// List all torrent links on the page
function listTorrentLinks() {
return document.querySelectorAll('.table-list a[href^="/torrent/"]');
}
// Clean the page title in order to get the torrent title
function cleanTitle(title) {
// Remove "Download " from the beginning
if (title.startsWith('Download ')) {
title = title.substring('Download '.length);
}
// Remove anything after " |"
let pipeIndex = title.indexOf(' Torrent |');
if (pipeIndex !== -1) {
title = title.substring(0, pipeIndex);
}
return title;
}
// Modify the H1 content on torrent pages to show the full title
function modifyH1ContentOnTorrentPages() {
if (window.location.pathname.startsWith('/torrent/')) {
let h1Element = document.querySelector('.box-info-heading h1');
if (h1Element) {
let cleanedTitle = cleanTitle(document.title);
h1Element.textContent = cleanedTitle;
}
}
}
// Fetch the content of the link
function fetchContent(link, onSuccess) {
GM_xmlhttpRequest({
method: 'GET',
url: link.href,
onload: function (response) {
let parser = new DOMParser();
let doc = parser.parseFromString(response.responseText, 'text/html');
onSuccess(doc);
},
});
}
// Process the link to update the title and add download buttons and images
function processLink(link) {
fetchContent(link, (doc) => {
updateLinkTitle(link, doc);
appendImages(link, doc);
addDownloadButtons(link, doc);
});
}
// Update the link title
function updateLinkTitle(link, doc) {
let title = cleanTitle(doc.querySelector('title').innerText);
link.innerText = title;
}
// Add download buttons next to the link
function addDownloadButtons(link, doc) {
let torrentLink = doc.querySelector("a[href*='itorrents.org/torrent/']");
let magnetLink = doc.querySelector("a[href^='magnet:?']");
let buttonsContainer = document.createElement('div');
buttonsContainer.style.display = 'flex';
buttonsContainer.style.alignItems = 'center';
buttonsContainer.style.gap = '5px';
buttonsContainer.style.marginTop = '10px';
// Torrent button
let torrentButton = document.createElement('a');
torrentButton.href = torrentLink ? torrentLink.href.replace('http:', 'https:') : '#';
torrentButton.title = 'Download torrent file';
torrentButton.innerHTML =
'';
// Magnet button
let magnetButton = document.createElement('a');
magnetButton.href = magnetLink ? magnetLink.href : '#';
magnetButton.title = 'Download via magnet';
magnetButton.innerHTML =
'';
buttonsContainer.appendChild(torrentButton);
buttonsContainer.appendChild(magnetButton);
link.after(buttonsContainer);
}
// Append images related to the torrent
function appendImages(link, doc) {
let images = doc.querySelectorAll('#description img');
if (images.length > 0) {
let flexContainer = document.createElement('div');
flexContainer.style.display = 'flex';
flexContainer.style.flexWrap = 'wrap';
flexContainer.style.gap = '10px';
flexContainer.style.marginTop = '10px';
let clonedImages = []; // Array to store cloned images
images.forEach((img, index) => {
let clonedImg = img.cloneNode(true);
if (img.hasAttribute('data-original')) {
clonedImg.src = img.getAttribute('data-original');
}
clonedImg.style.maxHeight = '100px';
clonedImg.style.setProperty('margin', '0', 'important');
// Show only the first VISIBLE_IMAGES images initially
clonedImg.style.display = index < VISIBLE_IMAGES ? 'block' : 'none';
flexContainer.appendChild(clonedImg);
clonedImages.push(clonedImg); // Store the cloned image
});
// Add "Show More/Less" button if there are more than VISIBLE_IMAGES images
if (images.length > VISIBLE_IMAGES) {
let showMoreButton = document.createElement('button');
showMoreButton.textContent = 'Show More';
showMoreButton.onclick = function () {
// Toggle visibility of additional images
let isShowingMore = showMoreButton.textContent === 'Show Less';
clonedImages.forEach((img, index) => {
if (index >= VISIBLE_IMAGES) {
img.style.display = isShowingMore ? 'none' : 'block';
}
});
showMoreButton.textContent = isShowingMore ? 'Show More' : 'Show Less';
};
flexContainer.appendChild(showMoreButton);
}
link.parentNode.insertBefore(flexContainer, link.nextSibling);
clonedImages.forEach((clonedImg) => {
// Mouseover event to show enlarged image
clonedImg.addEventListener('mouseover', function () {
showEnlargedImg(clonedImg.src);
});
// Mousemove event to update the position of the enlarged image
clonedImg.addEventListener('mousemove', updateEnlargedImgPosition);
// Mouseout event to remove enlarged image
clonedImg.addEventListener('mouseout', function () {
removeEnlargedImg();
});
});
}
}
// Function to show an enlarged image
function showEnlargedImg(imgSrc) {
const enlargedImg = document.createElement('img');
enlargedImg.src = imgSrc;
enlargedImg.style.position = 'fixed';
enlargedImg.style.width = '500px';
enlargedImg.style.height = '500px';
enlargedImg.style.pointerEvents = 'none'; // Ignore pointer events
enlargedImg.id = 'enlargedImg';
document.body.appendChild(enlargedImg);
}
// Function to update the position of the enlarged image
function updateEnlargedImgPosition(e) {
const enlargedImg = document.getElementById('enlargedImg');
if (enlargedImg) {
const viewportWidth = window.innerWidth;
const viewportHeight = window.innerHeight;
const imgWidth = 500; // Width of the enlarged image
const imgHeight = 500; // Height of the enlarged image
const offsetX = 10; // Horizontal offset from the cursor
const offsetY = 10; // Vertical offset from the cursor
let leftPosition = e.clientX + offsetX;
let topPosition = e.clientY + offsetY;
// Adjust position if the image goes out of the viewport
if (leftPosition + imgWidth > viewportWidth) {
leftPosition = e.clientX - imgWidth - offsetX;
}
if (topPosition + imgHeight > viewportHeight) {
topPosition = e.clientY - imgHeight - offsetY;
}
enlargedImg.style.left = leftPosition + 'px';
enlargedImg.style.top = topPosition + 'px';
}
}
// Function to remove enlarged image
function removeEnlargedImg() {
const enlargedImg = document.getElementById('enlargedImg');
if (enlargedImg) {
document.body.removeChild(enlargedImg);
}
}
// Replace the link text with the title and append images
function replaceLinkTextWithTitlesAndAppendImages() {
let torrentLinks = listTorrentLinks();
torrentLinks.forEach(processLink);
}
function injectCustomCSS() {
// Remove the max-width on the container
GM_addStyle('.container { max-width: none !important; }');
}
// Modify the function calls accordingly
replaceLinkTextWithTitlesAndAppendImages();
modifyH1ContentOnTorrentPages();
injectCustomCSS();
})();