Files
userscripts/r18dev_remove_duplicates.user.js

71 lines
2.0 KiB
JavaScript

// ==UserScript==
// @name r18.dev duplicate movie remover
// @namespace Violentmonkey Scripts
// @match https://r18.dev/videos/vod/movies/list/*
// @grant none
// @version 1.13
// @author Lukáš Kucharczyk
// @description Removes duplicate entries in the list of movies on r18.dev.
// @downloadURL https://git.kucharczyk.xyz/lukas/userscripts/raw/branch/main/r18dev_remove_duplicates.user.js
// @supportURL https://git.kucharczyk.xyz/lukas/userscripts
// @run-at document-idle
// ==/UserScript==
function filterVideos() {
// Select all .video containers
const videos = document.querySelectorAll('.video');
// Only log if we find videos to avoid spamming console during observation
if (videos.length > 0) {
console.log(`Found videos: ${videos.length}`);
}
// Regex to match "Letters-Numbers" (e.g., AAA-111)
const regex = /^[a-zA-Z]+-[0-9]+$/;
let removedCount = 0; // Changed to 'let' so it can be incremented
videos.forEach(video => {
const label = video.querySelector('.video-label');
// Safety check if label exists
if (label) {
const text = label.textContent.trim();
const linkCount = label.querySelectorAll('a').length;
// Remove if text doesn't match pattern OR label has more than 1 link
if (!regex.test(text) || linkCount > 1) {
video.remove();
removedCount++;
}
}
});
if (removedCount > 0) {
console.log(`Removed videos: ${removedCount}`);
}
}
// 1. Run immediately in case elements are already there
filterVideos();
// 2. Set up a MutationObserver to handle dynamic content (AJAX/Infinite Scroll)
const observer = new MutationObserver((mutations) => {
let shouldRun = false;
// Check if nodes were actually added
for (const mutation of mutations) {
if (mutation.addedNodes.length) {
shouldRun = true;
break;
}
}
if (shouldRun) {
filterVideos();
}
});
// Start observing the body for changes
observer.observe(document.body, {
childList: true,
subtree: true
});