// ==UserScript== // @name Sort Videos by Like Count // @namespace http://tampermonkey.net/ // @version 0.1 // @description Sort videos by like count on a specified website // @author NoName // @match https://jable.tv/* // @match https://jable.tv // @grant none // ==/UserScript== (function() { 'use strict'; // Function to extract the like count from the sub-title element function getLikeCount(subTitleElement) { if (subTitleElement) { const textContent = subTitleElement.textContent.trim(); console.log('Full text content:', textContent); // Extract all numbers from the text content const numbers = textContent.match(/\d+/g); if (numbers && numbers.length > 0) { const likeCount = parseInt(numbers[numbers.length - 1].replace(/\s/g, ''), 10); console.log('Parsed like count:', likeCount); return isNaN(likeCount) ? 0 : likeCount; } } return 0; } // Function to sort the videos within each parent div function sortVideosInParent(parent) { console.log('Sorting videos in parent:', parent); if (parent.classList.contains('owl-stage')) { sortCarouselVideos(parent); return; } const videos = Array.from(parent.children).map(item => { const v = item.matches('.video-img-box') ? item : item.querySelector('.video-img-box'); if (!v) { return null; } const subTitle = item.querySelector('.sub-title'); if (!subTitle) { return null; } const likeCount = getLikeCount(subTitle); console.log('Video element:', item, 'Like count:', likeCount); return { element: item, likeCount: likeCount }; }).filter(video => video !== null); videos.sort((a, b) => b.likeCount - a.likeCount); videos.forEach(video => { parent.appendChild(video.element); }); } function sortCarouselVideos(stage) { const groups = Array.from(stage.children).map(group => { const itemContainer = group.querySelector(':scope > .item'); if (!itemContainer) { return null; } const cards = Array.from(itemContainer.querySelectorAll(':scope > .video-img-box')); if (cards.length === 0) { return null; } return { group, itemContainer, slotCount: cards.length, cards }; }).filter(group => group !== null); const sortedCards = groups.flatMap(group => group.cards.map(card => { const subTitle = card.querySelector('.sub-title'); if (!subTitle) { return null; } return { element: card, likeCount: getLikeCount(subTitle) }; }).filter(card => card !== null)).sort((a, b) => b.likeCount - a.likeCount); if (sortedCards.length < 2) { return; } let index = 0; groups.forEach(group => { group.itemContainer.replaceChildren(); for (let i = 0; i < group.slotCount && index < sortedCards.length; i += 1) { group.itemContainer.appendChild(sortedCards[index].element); index += 1; } }); } function getSortableParent(videoBox) { const carouselStage = videoBox.closest('.owl-stage'); if (carouselStage) { const sortableCards = carouselStage.querySelectorAll('.video-img-box .sub-title'); if (sortableCards.length >= 2) { return carouselStage; } return null; } let current = videoBox; while (current && current.parentElement) { const parent = current.parentElement; const sortableChildren = Array.from(parent.children).filter(child => child.matches('.video-img-box') || child.querySelector('.video-img-box')); if (sortableChildren.length >= 2 && (current.matches('.video-img-box') || current.querySelector('.video-img-box'))) { return parent; } current = parent; } return null; } // Function to find all parent divs and sort their child videos function sortAllVideos() { const videoContainers = document.querySelectorAll('.video-img-box'); const parents = new Set(); videoContainers.forEach(v => { const parent = getSortableParent(v); if (!parent) { return; } console.log('Found parent:', parent); parents.add(parent); }); parents.forEach(parent => { sortVideosInParent(parent); }); } // Add a sort button after the element with class "inactive-color fs-2 mb-0" function addSortButton() { const targetElement = document.querySelector('.inactive-color.fs-2.mb-0'); if (targetElement) { const sortItem = document.createElement('li'); const sortLink = document.createElement('a'); sortLink.href = '#'; sortLink.textContent = '排序'; sortLink.style.marginLeft = '10px'; sortLink.addEventListener('click', function(event) { event.preventDefault(); sortAllVideos(); }); sortItem.appendChild(sortLink); targetElement.parentNode.insertBefore(sortItem, targetElement.nextSibling); console.log('Sort button added after the target element'); } } // Add CSS to override the preview thumb image container dimensions function addCustomStyles() { if (document.getElementById('tm-preview-thumb-style')) { return; } const style = document.createElement('style'); style.id = 'tm-preview-thumb-style'; style.textContent = ` :root { --tm-preview-scale: 0.5; } .plyr__preview-thumb { position: absolute !important; left: 0px !important; bottom: 15px !important; top: auto !important; right: auto !important; transform: scale(var(--tm-preview-scale)) !important; transform-origin: bottom left !important; z-index: 99999 !important; } `; document.head.appendChild(style); console.log('Custom styles added for preview thumb image container'); } // Run the sort function after the DOM content has loaded window.addEventListener('load', function() { addCustomStyles(); addSortButton(); sortAllVideos(); }) })();