Youtube Номерация роликов

Номерация роликов Youtube

// ==UserScript==
// @name           Youtube Номерация роликов
// @version        2025.08.15.1
// @description    Номерация роликов Youtube
// @match          https://www.youtube.com/@*
// @author         Rainbow-Spike
// @namespace      https://greasyfork.org/users/7568
// @homepage       https://greasyfork.org/ru/users/7568-rainbow-spike
// @icon           https://www.google.com/s2/favicons?domain=youtube.com
// @grant          none
// ==/UserScript==

let toLow = 1;
const splitSign = " ⹀ ";

function h ( tag, props = { }, children = [ ] ) {
	const element = Object . assign ( document . createElement ( tag ), props );
	element . append ( ...children );
	return element;
}

function Toggle ( a ) {
	toLow = !a;
	const allVideos = document . querySelectorAll ( 'ytd-rich-item-renderer' );

	allVideos . forEach ( ( e ) => {
		if ( e . classList . contains ( "js-stop" ) ) {
			e . querySelector ( '#video-title' ) . innerHTML = e . querySelector ( '#video-title' ) . innerHTML . split ( splitSign ) [ 1 ];
			e . classList . remove ( "js-stop" );
		}
	} )
}

function Action ( ) {
	const allVideos = document . querySelectorAll ( 'ytd-rich-item-renderer' );
	const countVideos = document . querySelector ( 'yt-content-metadata-view-model div:last-child span:last-child span:last-child' ) . innerHTML . split ( " " ) [ 0 ] || allVideos . length;
	const countLength = countVideos . toString ( ) . length;

	allVideos . forEach ( ( e, i ) => {
		const videoCounter = ( toLow ? countVideos - i : i + 1 ) . toString ( ) . padStart ( countLength, '0' );
		if ( ! e . classList . contains ( "js-stop" ) ) {
			e . querySelector ( '#video-title' ) . innerHTML = videoCounter + splitSign + e . querySelector ( '#video-title' ) . innerHTML;
			e . classList . add ( "js-stop" );
		}
	} )
}

function InsertButton ( ) {
	document . body . appendChild (
		h ( 'div', { id: 'yvn' }, [
			h ( 'style', {
				innerHTML:	`#yvn { background-color: white; border: 3px solid #1ad4df; border-radius: 13px; bottom: 5px; opacity: 0.8; padding: 5px; position: fixed; right: 25px }
							#yvn * { font-size: 18px; margin: 2px }
							#yvn [type="button"] { display: block }
							#yvn input:hover { border-color: #eaf1f1 }`
			} ),
			h ( 'input', { type: 'button', value: 'Номерование', title: "Номерование", onclick: ( event ) => Action ( ) } ),
			h ( 'span', { innerHTML: 'По убыванию?' } ),
			h ( 'input', { type: 'checkbox', value: 'По убыванию?', checked: 'checked', onclick: ( event ) => Toggle ( toLow ) } )
		] )
	)
}

InsertButton ( )