Motherless PervertMonkey

Infinite scroll [optional], Filter by Title, Uploader and Duration, Sort by Duration and Views

이 스크립트를 설치하려면 Tampermonkey, Greasemonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

이 스크립트를 설치하려면 Tampermonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Userscripts와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 유저 스크립트 관리자 확장 프로그램이 필요합니다.

(이미 유저 스크립트 관리자가 설치되어 있습니다. 설치를 진행합니다!)

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

(이미 유저 스타일 관리자가 설치되어 있습니다. 설치를 진행합니다!)

// ==UserScript==
// @name         Motherless PervertMonkey
// @namespace    pervertmonkey
// @version      5.0.25
// @author       violent-orangutan
// @description  Infinite scroll [optional], Filter by Title, Uploader and Duration, Sort by Duration and Views
// @license      MIT
// @icon         https://www.google.com/s2/favicons?sz=64&domain=motherless.xxx
// @homepage     https://github.com/smartacephale/sleazy-fork#readme
// @homepageURL  https://sleazyfork.org/en/users/1253342-smartacephale
// @source       https://github.com/smartacephale/sleazy-fork
// @supportURL   https://github.com/smartacephale/sleazy-fork/issues
// @match        https://motherless.xxx/*
// @require      https://cdn.jsdelivr.net/npm/[email protected]/dist/core/pervertmonkey.core.umd.js
// @grant        GM_addElement
// @grant        GM_addStyle
// @grant        unsafeWindow
// @run-at       document-idle
// ==/UserScript==

var ___core = window.pervertmonkey.core || pervertmonkey.core;
var ___utils = ___core;


(function(___core, ___utils) {
	"use strict";
	var _GM_addElement = (() => typeof GM_addElement != "undefined" ? GM_addElement : void 0)();
	var _GM_addStyle = (() => typeof GM_addStyle != "undefined" ? GM_addStyle : void 0)();
	var _unsafeWindow = (() => typeof unsafeWindow != "undefined" ? unsafeWindow : void 0)();
	_unsafeWindow.__is_premium = true;
	var $ = _unsafeWindow.$;
	var rules = new ___core.Rules({
		containerSelector: ".content-inner",
		thumbs: { selector: ".thumb-container, .mobile-thumb" },
		thumb: { selectors: {
			uploader: ".uploader",
			title: ".title",
			duration: ".size",
			views: {
				selector: ".hits",
				type: "float"
			}
		} },
		thumbImg: { strategy: "auto" },
		paginationStrategyOptions: { paginationSelector: ".pagination_link, .ml-pagination" },
		animatePreview,
		gropeStrategy: "all-in-all",
		schemeOptions: [
			"Title Filter",
			"Uploader Filter",
			"Duration Filter",
			"Sort By",
			"Badge",
			{
				title: "Advanced",
				content: [{
					applyTitleFiltersToSearch: false,
					label: "apply title filters to search"
				}]
			}
		]
	});
	function animatePreview(_) {
		const tick = new ___utils.Tick(500);
		function onOver(target) {
			$(".video").off();
			const container = target.querySelector(".video");
			if (!container) return;
			const img = container.querySelector("img.static");
			const stripSrc = img.getAttribute("data-strip-src");
			container.classList.toggle("animating");
			let overlay = img.nextElementSibling;
			if (!overlay || overlay.tagName !== "DIV") {
				overlay = document.createElement("div");
				overlay.setAttribute("style", "z-index: 8; position: absolute; top: 0; left: 0; pointer-events: none;");
				img.after(overlay);
			}
			overlay.style.display = "block";
			let j = 0;
			const containerHeight = container.offsetHeight + 20;
			const w = img.offsetWidth;
			const h = img.offsetHeight;
			const widthRatio = Math.floor(1000.303 * w / 100);
			const heightRatio = Math.floor(228.6666 * h / 100);
			const verticalOffset = (containerHeight - h) / 2;
			tick.start(() => {
				Object.assign(overlay.style, {
					width: `${w}px`,
					height: `${containerHeight}px`,
					backgroundImage: `url('${stripSrc}')`,
					backgroundSize: `${widthRatio}px ${heightRatio}px`,
					backgroundPosition: `-${j++ * w % widthRatio}px ${verticalOffset}px`
				});
			});
			return () => {
				tick.stop();
				container.classList.toggle("animating");
				overlay.style.display = "none";
			};
		}
		___utils.OnHover.create(document.body, ".thumb-container, .mobile-thumb", onOver);
	}
	function fixURLs() {
		document.querySelectorAll(".gallery-container").forEach((g) => {
			const x = g.innerText.match(/([\d|.]+)k? videos/gi)?.[0];
			const header = parseInt(x) > 0 ? "/GV" : "/GI";
			g.querySelectorAll("a").forEach((a) => {
				a.href = a.href.replace(/\/G/, () => header);
			});
		});
		document.querySelectorAll("a[href^=\"/term/\"]:not([href^=\"/term/videos/\"]):not(.pop):not([rel])").forEach((a) => {
			a.href = a.href.replace(/[\w|+]+$/, (v) => `videos/${v}?term=${v}`);
		});
		document.querySelectorAll("#media-groups-container a[href^=\"/g/\"]").forEach((a) => {
			a.href = a.href.replace(/\/g\//, "/gv/");
		});
	}
	function mobileGalleryToDesktop(e) {
		e.querySelector(".clear-left")?.remove();
		const container = e.firstElementChild;
		container.appendChild(container.nextElementSibling);
		e.className = "thumb-container gallery-container";
		container.className = "desktop-thumb image medium";
		(container.firstElementChild?.nextElementSibling).className = "gallery-captions";
		(0, ___utils.replaceElementTag)(container.firstElementChild, "a");
		return e;
	}
	async function desktopAddMobGalleries() {
		const galleries = document.querySelector(".media-related-galleries");
		if (!galleries) return;
		await new Promise((resolve) => {
			(0, ___utils.waitForElementToAppear)(document, ".thumb-container.gallery-container", resolve);
		});
		const mobGalleries = (await (0, ___utils.fetchWith)(window.location.href, {
			type: "html",
			mobile: true
		})).querySelectorAll(".ml-gallery-thumb");
		const galleriesContainer = galleries.querySelector(".content-inner");
		for (const x of mobGalleries.values()) {
			const mobGallery = mobileGalleryToDesktop(x);
			const mobGalleryId = mobGallery.querySelector("a").href.split("/").at(-1);
			if (galleriesContainer.querySelector(`a[href*=${mobGalleryId}]`)) continue;
			galleriesContainer.append(mobGallery);
		}
	}
	_GM_addStyle(`
.img-container, .desktop-thumb { min-height: 150px; max-height: 150px; }

.group-minibio, .gallery-container { display: block !important; }

.ml-masonry-images.masonry-columns-4 .content-inner { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); }
.ml-masonry-images.masonry-columns-6 .content-inner { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); }
.ml-masonry-images.masonry-columns-8 .content-inner { display: grid; grid-template-columns: repeat(8, minmax(0, 1fr)); }
`);
	document.querySelector(".ml-pagination")?.before(_GM_addElement("div", { class: "clear-left" }));
	function applySearchFilters() {
		let pathname = window.location.pathname;
		const wordsToFilter = rules.store.state.filterExcludeWords.match(/\w+/g) || [];
		wordsToFilter.filter((w) => !pathname.includes(w)).forEach((w) => {
			pathname += `+-${w.trim()}`;
		});
		if (wordsToFilter.some((w) => !window.location.href.includes(w))) window.location.href = pathname;
	}
	desktopAddMobGalleries().then(() => fixURLs());
	if (/^\/term\//.test(location.pathname) && rules.store.state.applyTitleFiltersToSearch) applySearchFilters();
})(___core, ___utils);