Automatically sort video results in a page on /videos, /images, /subscriptions, /users, and sidebars using customizable sort function.
当前为
// ==UserScript==
// @name Iwara Custom Sort
// @version 0.118
// @grant GM.setValue
// @grant GM.getValue
// @grant GM.deleteValue
// @match https://ecchi.iwara.tv/*
// @match https://www.iwara.tv/*
// @match http://ecchi.iwara.tv/*
// @match http://www.iwara.tv/*
// @description Automatically sort video results in a page on /videos, /images, /subscriptions, /users, and sidebars using customizable sort function.
// @namespace https://greasyfork.org/users/245195
// ==/UserScript==
/* jshint esversion: 6 */
'use strict';
const logDebug = (...args) => {
const debugging = true;
if (debugging) {
console.log(...args);
}
}
logDebug('Parsed.');
const parsePrefixed = (str) => {
return Number.parseFloat(str) * (str.includes('k') ? 1000 : 1);
}
const getNearbyNumber = (element) => {
return element ? parsePrefixed(element.parentElement.textContent) : 0;
}
const sortVideos = (container, sortValueExpression) => {
GM.setValue('sortValue', sortValueExpression);
const evalSortValue = (item) => new Function('views', 'likes', 'ratio', `return (${sortValueExpression})`)(
item.viewCount,
item.likeCount,
Math.min(item.likeCount / Math.max(1, item.viewCount), 1)
);
const videoDivs = Array.from(container.querySelectorAll('.clearfix'));
const videoItem = videoDivs.map((div) => ({
div,
viewCount: getNearbyNumber(div.querySelector('.glyphicon-eye-open')),
likeCount: getNearbyNumber(div.querySelector('.glyphicon-heart')),
}))
.sort((itemA, itemB) => evalSortValue(itemB) - evalSortValue(itemA));
videoDivs.map((div) => {
const anchor = document.createElement('div');
div.before(anchor);
return anchor;
})
.forEach((div, index) => div.replaceWith(videoItem[index].div));
};
const sortAllVideos = (containers, sortValueExpression) => {
let sortedCount = 0;
try {
containers.forEach((container) => {
sortVideos(container, sortValueExpression);
sortedCount++;
});
} catch (message) {
alert(message);
}
logDebug(`${sortedCount} containers sorted.`);
};
const requestMorePages = async (URL, pageCount) => {
/*
const params = URL.searchParams;
const page = params.has('page') ? Number.parseInt(params.get('page')) : 0;
params.set('page', page + 1);
try {
const newPage = await fetch(URL);
logDebug(page, pageCount, URL, new DOMParser().parseFromString(await newPage.text(), 'text/html'));
} catch (message) {
logDebug(message);
}
*/
}
(async () => {
const videoContainers = Array.from(document.querySelectorAll('.views-responsive-grid'));
if (videoContainers.length === 0) {
return;
}
if (/\/(videos|images|subscriptions)/.test(location.pathname)) {
const additionalPageCount = 2;
requestMorePages(new URL(location), additionalPageCount);
}
const sortValueInput = document.createElement('input');
sortValueInput.type = 'text';
sortValueInput.value = await GM.getValue('sortValue', '100 * ratio + Math.sqrt(likes) / 25');
const UIDiv = document.createElement('div');
UIDiv.style.display = 'inline';
UIDiv.style.margin = '5px';
const sortButton = document.createElement('button');
sortButton.innerHTML = 'Sort';
UIDiv.append(sortValueInput, sortButton);
sortValueInput.addEventListener('keyup', (event) => {
if (event.key !== "Enter") {
return;
}
sortButton.click();
event.preventDefault();
});
const temp = document.querySelector('.list-inline');
if (temp) {
temp.append(UIDiv);
} else {
document.querySelector('#user-links')
.prepend(UIDiv);
}
sortButton.addEventListener('click', () => sortAllVideos(videoContainers, sortValueInput.value));
sortAllVideos(videoContainers, sortValueInput.value);
})();