mirror of
				https://github.com/chylex/Userscripts.git
				synced 2025-10-31 21:17:16 +01:00 
			
		
		
		
	Compare commits
	
		
			9 Commits
		
	
	
		
			fa104cf684
			...
			vim-bindin
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 390626f99f | |||
| 7319ee255e | |||
| de4fa3b7a5 | |||
| 035aed7554 | |||
| 602ad9298d | |||
| 98097ef8c1 | |||
| 1bf299d4fe | |||
| 9dc53e3e1d | |||
| bd10edeb73 | 
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| .idea | ||||
							
								
								
									
										30
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								README.md
									
									
									
									
									
								
							| @@ -66,11 +66,7 @@ Before you [report an issue](https://github.com/chylex/Userscripts/issues/new) ( | ||||
|     <tbody> | ||||
|         <tr> | ||||
|             <th width="110px" rowspan="5">YouTube</th> | ||||
|             <td width="325px"><a href="#activity-check-removal">Activity Check Removal</a></td> | ||||
|             <td>Script</td> | ||||
|         </tr> | ||||
|         <tr> | ||||
|             <td><a href="#block-youtube-playlists">Block YouTube Playlists</a></td> | ||||
|             <td width="325px"><a href="#block-youtube-playlists">Block YouTube Playlists</a></td> | ||||
|             <td>Script</td> | ||||
|         </tr> | ||||
|         <tr> | ||||
| @@ -81,6 +77,10 @@ Before you [report an issue](https://github.com/chylex/Userscripts/issues/new) ( | ||||
|             <td><a href="#hide-youtube-seek-bar--duration">Hide YouTube Seek Bar & Duration</a></td> | ||||
|             <td>Script</td> | ||||
|         </tr> | ||||
|         <tr> | ||||
|             <td><a href="#redirect-youtube-shorts">Redirect YouTube Shorts</a></td> | ||||
|             <td>Script</td> | ||||
|         </tr> | ||||
|         <tr> | ||||
|             <td><a href="#theater-fullscreen--transparent-chat">Theater Fullscreen + Transparent Chat</a></td> | ||||
|             <td>Script</td> | ||||
| @@ -154,19 +154,11 @@ Overlays Twitch chat over the video to save space. Includes many customizations | ||||
| --- | ||||
| ### YouTube | ||||
|  | ||||
| #### Activity Check Removal | ||||
| Removes activity check that interrupts video playback. **This script is obsolete**.   | ||||
| \[ [Automatically updated](https://github.com/chylex/Userscripts/raw/master/YouTube/ActivityCheckRemoval.user.js) \] | ||||
| \- | ||||
| \[ [Manually updated](https://github.com/chylex/Userscripts/raw/2ddfdcd8cffb796830ff04847f43f2bf91fb0ffc/YouTube/ActivityCheckRemoval.user.js) \] | ||||
| \- | ||||
| \[ [Source code](https://github.com/chylex/Userscripts/blob/master/YouTube/ActivityCheckRemoval.user.js) \] | ||||
|  | ||||
| #### Block YouTube Playlists | ||||
| Removes playlists from YouTube video URLs.   | ||||
| \[ [Automatically updated](https://github.com/chylex/Userscripts/raw/master/YouTube/BlockPlaylists.user.js) \] | ||||
| \- | ||||
| \[ [Manually updated](https://github.com/chylex/Userscripts/raw/b74c26ed01640db4f6d0a06f67d6e25627fb07be/YouTube/BlockPlaylists.user.js) \] | ||||
| \[ [Manually updated](https://github.com/chylex/Userscripts/raw/98097ef8c14ab84ff0dc7463bbe55a363890bb6d/YouTube/BlockPlaylists.user.js) \] | ||||
| \- | ||||
| \[ [Source code](https://github.com/chylex/Userscripts/blob/master/YouTube/BlockPlaylists.user.js) \] | ||||
|  | ||||
| @@ -186,6 +178,14 @@ Hides all mentions of video durations by default. Press 'AltGr' to toggle. | ||||
| \- | ||||
| \[ [Source code](https://github.com/chylex/Userscripts/blob/master/YouTube/HideSeekBarAndDuration.user.js) \] | ||||
|  | ||||
| #### Redirect YouTube Shorts | ||||
| Redirects YouTube shorts to normal video URLs.   | ||||
| \[ [Automatically updated](https://github.com/chylex/Userscripts/raw/master/YouTube/RedirectShorts.user.js) \] | ||||
| \- | ||||
| \[ [Manually updated](https://github.com/chylex/Userscripts/raw/035aed7554c89fee66a6278f4fcf73292821b7f5/YouTube/RedirectShorts.user.js) \] | ||||
| \- | ||||
| \[ [Source code](https://github.com/chylex/Userscripts/blob/master/YouTube/RedirectShorts.user.js) \] | ||||
|  | ||||
| #### Theater Fullscreen + Transparent Chat | ||||
| In theater mode, it expands video to full screen, makes chat transparent and overlays it over the video. Note that colors of images in chat will be inverted, and the player controls may behave strangely. **Requires classic YouTube layout,** you can use the third-party [Youtube - Restore Classic](https://greasyfork.org/en/scripts/34818-youtube-restore-classic) script for that.   | ||||
| \[ [Automatically updated](https://github.com/chylex/Userscripts/raw/master/YouTube/TheaterFullscreenTransparentChat.user.js) \] | ||||
| @@ -203,7 +203,7 @@ In theater mode, it expands video to full screen, makes chat transparent and ove | ||||
| Reverts to the old Vector design.   | ||||
| \[ [Automatically updated](https://github.com/chylex/Userscripts/raw/master/Wikipedia/OldDesign.user.js) \] | ||||
| \- | ||||
| \[ [Manually updated](https://github.com/chylex/Userscripts/raw/2b6bad9b2ba7a25c99e5f5b705de61e3661e89ef/Wikipedia/OldDesign.user.js) \] | ||||
| \[ [Manually updated](https://github.com/chylex/Userscripts/raw/bd10edeb73ded1b0af0c4c715ef4399e9db248e8/Wikipedia/OldDesign.user.js) \] | ||||
| \- | ||||
| \[ [Source code](https://github.com/chylex/Userscripts/blob/master/Wikipedia/OldDesign.user.js) \] | ||||
|  | ||||
|   | ||||
							
								
								
									
										279
									
								
								Vim/VimBindings.user.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										279
									
								
								Vim/VimBindings.user.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,279 @@ | ||||
| // ==UserScript== | ||||
| // @name         Vim Bindings | ||||
| // @description  Reformats the Vim index help page and adds custom notes to each binding. | ||||
| // @author       chylex | ||||
| // @version      1 | ||||
| // @license      MIT | ||||
| // @namespace    https://chylex.com | ||||
| // @homepageURL  https://github.com/chylex/Userscripts | ||||
| // @supportURL   https://github.com/chylex/Userscripts/issues | ||||
| // @include      https://vimhelp.org/index.txt.html | ||||
| // @run-at       document-end | ||||
| // @grant        none | ||||
| // ==/UserScript== | ||||
|  | ||||
| const settings = loadSettings(); | ||||
|  | ||||
| function loadSettings() { | ||||
| 	try { | ||||
| 		const json = localStorage.getItem("vim_binding_settings"); | ||||
| 		return json === null ? {} : JSON.parse(json); | ||||
| 	} catch (e) { | ||||
| 		console.error("Could not load binding settings", e); | ||||
| 		return null; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| function saveSettings() { | ||||
| 	localStorage.setItem("vim_binding_settings", JSON.stringify(settings)); | ||||
| } | ||||
|  | ||||
| appendElement(document.head, "style").textContent = ` | ||||
| #vh-content { | ||||
|   flex: 1 1 auto; | ||||
| } | ||||
|  | ||||
| #vh-content pre { | ||||
|   width: 100%; | ||||
|   margin: 0; | ||||
| } | ||||
|  | ||||
| table { | ||||
|   border-collapse: collapse; | ||||
| } | ||||
|  | ||||
| tr.h { | ||||
|   border-bottom: 2px dashed var(--aqua); | ||||
| } | ||||
|  | ||||
| tr.h td, tr:has(+ tr.subsection) td { | ||||
|   padding-bottom: 12px; | ||||
| } | ||||
|  | ||||
| tr.h + tr td, tr.subsection + tr td { | ||||
|   padding-top: 12px; | ||||
| } | ||||
|  | ||||
| td { | ||||
|   padding: 2px 8px; | ||||
| } | ||||
|  | ||||
| td:first-child { | ||||
|   padding-left: 0; | ||||
| } | ||||
|  | ||||
| td:last-child { | ||||
|   padding-right: 0; | ||||
| } | ||||
|  | ||||
| tr.subsection td { | ||||
|   padding-top: 12px; | ||||
|   padding-bottom: 12px; | ||||
|   border-top: 1px dashed var(--aqua); | ||||
|   border-bottom: 1px dashed var(--aqua); | ||||
| } | ||||
|  | ||||
| tr[data-binding-value="used"], | ||||
| tr[data-binding-value="changed"], | ||||
| tr[data-binding-value="rebound"], | ||||
| tr[data-binding-value="not-used"] { | ||||
|   opacity: 0.35; | ||||
| } | ||||
|  | ||||
| tr.missing { | ||||
|   opacity: 0.35; | ||||
|   text-decoration: line-through; | ||||
| } | ||||
|  | ||||
| select { | ||||
|   border: 0; | ||||
|   padding: 3px 5px; | ||||
|   font-size: 0.82rem; | ||||
| } | ||||
|  | ||||
| select, select option { | ||||
|   font-family: monospace; | ||||
|   text-align: center; | ||||
| } | ||||
| `; | ||||
|  | ||||
| let headingIndex = 0; | ||||
|  | ||||
| /** @var {Object<string, HTMLSelectElement[]>} */ | ||||
| const selectsByBinding = {}; | ||||
|  | ||||
| for (const headingEle of document.querySelectorAll("span[class='h']:has(+ span[class='h'])")) { | ||||
| 	const delimiterEle = headingEle.nextElementSibling; | ||||
| 	 | ||||
| 	const columnNames = headingEle.textContent.split(/(?<!^)(?:\t+\s*|(?<=note ))(?!$)/).map(name => name.trim()); | ||||
| 	 | ||||
| 	const tableEle = document.createElement("table"); | ||||
| 	addHeadingRow(tableEle, columnNames); | ||||
| 	 | ||||
| 	let currentNode = delimiterEle.nextSibling; | ||||
| 	let html = ""; | ||||
| 	 | ||||
| 	while (currentNode !== null && !isTagWithClass(currentNode, "SPAN", "h")) { | ||||
| 		html += currentNode.nodeType === Node.ELEMENT_NODE ? currentNode.outerHTML : currentNode.textContent; | ||||
| 		 | ||||
| 		const nextNode = currentNode.nextSibling; | ||||
| 		currentNode.remove(); | ||||
| 		currentNode = nextNode; | ||||
| 	} | ||||
| 	 | ||||
| 	for (const line of html.split(/\n(?=<a|\t{1,3}[^\t]|\n)/)) { | ||||
| 		addContentRow(tableEle, line, columnNames); | ||||
| 	} | ||||
| 	 | ||||
| 	headingEle.insertAdjacentElement("beforebegin", tableEle); | ||||
| 	headingEle.remove(); | ||||
| 	delimiterEle.remove(); | ||||
| 	 | ||||
| 	++headingIndex; | ||||
| } | ||||
|  | ||||
| function isColumnRightAligned(columnName) { | ||||
| 	return columnName === "note"; | ||||
| } | ||||
|  | ||||
| function addHeadingRow(table, columnNames) { | ||||
| 	const tr = appendElement(table, "tr"); | ||||
| 	tr.classList.add("h"); | ||||
| 	 | ||||
| 	appendElement(tr, "td"); | ||||
| 	 | ||||
| 	for (const columnName of columnNames) { | ||||
| 		const td = appendElement(tr, "td"); | ||||
| 		td.innerText = columnName; | ||||
| 		 | ||||
| 		if (isColumnRightAligned(columnName)) { | ||||
| 			td.style.textAlign = "right"; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| function addContentRow(table, line, columnNames) { | ||||
| 	if (line.includes("Meta characters (0x80 to 0xff, 128 to 255)")) { | ||||
| 		return; | ||||
| 	} | ||||
| 	 | ||||
| 	// console.info(line); | ||||
| 	 | ||||
| 	const columnCount = columnNames.length; | ||||
| 	const matches = line.match(/^(?:(<a .+?<\/a>)\s+|\t{2})(.*?)(?:(?:\t+?\s*| {2}\t*|(?<=] )|(?<=<span class="s">{.+?}<\/span> (?!(?:<a .+?class="s">.+?<\/a> )?<span class="s">{.+?}<\/span>)))(?:(\d+(?:,\d+)*)\s+)?(.*))?$/s); | ||||
| 	 | ||||
| 	if (matches === null) { | ||||
| 		addSubsectionRow(table, line, columnCount); | ||||
| 		return; | ||||
| 	} | ||||
| 	 | ||||
| 	/** @var {HTMLTableRowElement} */ | ||||
| 	const tr = appendElement(table, "tr"); | ||||
| 	 | ||||
| 	/** @var {HTMLTableCellElement[]} */ | ||||
| 	const tds = [ appendElement(tr, "td") ]; | ||||
| 	 | ||||
| 	for (let matchIndex = 1; matchIndex < matches.length; matchIndex++) { | ||||
| 		let td = tds[tds.length - 1]; | ||||
| 		 | ||||
| 		if (matchIndex <= columnCount) { | ||||
| 			tds.push(td = appendElement(tr, "td")); | ||||
| 			 | ||||
| 			if (isColumnRightAligned(columnNames[matchIndex - 1])) { | ||||
| 				td.style.textAlign = "right"; | ||||
| 			} | ||||
| 		} | ||||
| 		else if (td.innerHTML.length > 0) { | ||||
| 			td.innerHTML += " "; | ||||
| 		} | ||||
| 		 | ||||
| 		const match = matches[matchIndex]; | ||||
| 		if (match !== undefined) { | ||||
| 			td.innerHTML += match | ||||
| 				.replaceAll("\t", "") | ||||
| 				.replace(/\n\s*/g, " ") | ||||
| 				.replace("<MiddleMouse>", "<MiddleMouse>") | ||||
| 				.trim(); | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	const bindingElements = tds[1].getElementsByClassName("l"); | ||||
| 	 | ||||
| 	if (bindingElements.length === 1) { | ||||
| 		const binding = bindingElements[0].innerText; | ||||
| 		const select = appendElement(tds[0], "select"); | ||||
| 		 | ||||
| 		addOption(select, "TBD", ""); | ||||
| 		addOption(select, "Used", "used"); | ||||
| 		addOption(select, "Changed", "changed"); | ||||
| 		addOption(select, "Rebound", "rebound"); | ||||
| 		addOption(select, "Interested", "interested"); | ||||
| 		addOption(select, "Not Used", "not-used"); | ||||
| 		 | ||||
| 		const loadedValue = settings[binding]; | ||||
| 		select.value = loadedValue ?? ""; | ||||
| 		tr.setAttribute("data-binding-value", loadedValue); | ||||
| 		 | ||||
| 		select.addEventListener("change", _ => { | ||||
| 			const newValue = select.value; | ||||
| 			 | ||||
| 			for (const otherSelect of selectsByBinding[binding]) { | ||||
| 				if (otherSelect !== select) { | ||||
| 					otherSelect.value = newValue; | ||||
| 				} | ||||
| 				 | ||||
| 				otherSelect.closest("tr").setAttribute("data-binding-value", newValue); | ||||
| 			} | ||||
| 			 | ||||
| 			if (!newValue) { | ||||
| 				delete settings[binding]; | ||||
| 			} | ||||
| 			else { | ||||
| 				settings[binding] = newValue; | ||||
| 			} | ||||
| 			 | ||||
| 			saveSettings(); | ||||
| 		}); | ||||
| 		 | ||||
| 		if (!(binding in selectsByBinding)) { | ||||
| 			selectsByBinding[binding] = []; | ||||
| 		} | ||||
| 		 | ||||
| 		selectsByBinding[binding].push(select); | ||||
| 	} | ||||
| 	else { | ||||
| 		tr.classList.add("missing"); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| function addSubsectionRow(table, line, columnCount) { | ||||
| 	const text = line.trim(); | ||||
| 	if (text.length === 0) { | ||||
| 		return; | ||||
| 	} | ||||
| 	 | ||||
| 	/** @var {HTMLTableRowElement} */ | ||||
| 	const tr = appendElement(table, "tr"); | ||||
| 	tr.classList.add("subsection"); | ||||
| 	 | ||||
| 	/** @var {HTMLTableCellElement} */ | ||||
| 	const td = appendElement(tr, "td"); | ||||
| 	td.innerHTML = text; | ||||
| 	td.colSpan = columnCount; | ||||
| } | ||||
|  | ||||
| function isTagWithClass(node, tagName, className) { | ||||
| 	return node.nodeType === Node.ELEMENT_NODE && node.tagName === tagName && node.classList.contains(className); | ||||
| } | ||||
|  | ||||
| function appendElement(target, tagName) { | ||||
| 	const ele = document.createElement(tagName); | ||||
| 	target.appendChild(ele); | ||||
| 	return ele; | ||||
| } | ||||
|  | ||||
| function addOption(select, name, value) { | ||||
| 	const option = appendElement(select, "option"); | ||||
| 	option.innerText = name; | ||||
| 	option.value = value; | ||||
| } | ||||
| @@ -2,14 +2,14 @@ | ||||
| // @name         Old Wikipedia Design | ||||
| // @description  Reverts to the old Vector design. | ||||
| // @author       Vusys, chylex | ||||
| // @version      1 | ||||
| // @version      2 | ||||
| // @license      MIT | ||||
| // @namespace    https://chylex.com | ||||
| // @homepageURL  https://github.com/chylex/Userscripts | ||||
| // @supportURL   https://github.com/chylex/Userscripts/issues | ||||
| // @include      https://*.wikipedia.org/* | ||||
| // @exclude      https://*.wikipedia.org/ | ||||
| // @run-at       document-end | ||||
| // @run-at       document-start | ||||
| // @grant        none | ||||
| // ==/UserScript== | ||||
|  | ||||
| @@ -25,9 +25,11 @@ | ||||
| 		return; | ||||
| 	} | ||||
| 	 | ||||
| 	for (const a of document.getElementsByTagName("a")) { | ||||
| 		if (a.hostname.includes("wikipedia.org")) { | ||||
| 			a.href = fixUrl(a.href); | ||||
| 	document.addEventListener("DOMContentLoaded", function() { | ||||
| 		for (const a of document.getElementsByTagName("a")) { | ||||
| 			if (a.hostname.includes("wikipedia.org")) { | ||||
| 				a.href = fixUrl(a.href); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	}); | ||||
| })(); | ||||
|   | ||||
| @@ -1,35 +0,0 @@ | ||||
| // ==UserScript== | ||||
| // @name         YouTube Activity Check Removal | ||||
| // @description  Removes activity check that interrupts video playback. | ||||
| // @version      1 | ||||
| // @license      MPL-2.0 | ||||
| // @namespace    https://chylex.com | ||||
| // @homepageURL  https://github.com/chylex/Userscripts | ||||
| // @supportURL   https://github.com/chylex/Userscripts/issues | ||||
| // @include      https://youtube.com/* | ||||
| // @include      https://*.youtube.com/* | ||||
| // @run-at       document-end | ||||
| // @grant        none | ||||
| // @noframes | ||||
| // ==/UserScript== | ||||
|  | ||||
| var timeout = 0; | ||||
|  | ||||
| var check = setInterval(function(){ | ||||
|   if (_yt_www.J){ | ||||
|     clearInterval(check); | ||||
|      | ||||
|     var prev = _yt_www.J; | ||||
|  | ||||
|     _yt_www.J = function(cls){ | ||||
|       if (cls && cls.startsWith("youthere-")){ | ||||
|         return null; | ||||
|       } | ||||
|  | ||||
|       return prev.apply(this, arguments); | ||||
|     }; | ||||
|   } | ||||
|   else if (++timeout > 500){ // average should be about 5-10 | ||||
|     clearInterval(check); | ||||
|   } | ||||
| }, 1); | ||||
| @@ -1,7 +1,7 @@ | ||||
| // ==UserScript== | ||||
| // @name         Block YouTube Playlists | ||||
| // @description  Removes playlists from YouTube video URLs. | ||||
| // @version      1 | ||||
| // @version      2 | ||||
| // @license      MPL-2.0 | ||||
| // @namespace    https://chylex.com | ||||
| // @homepageURL  https://github.com/chylex/Userscripts | ||||
| @@ -13,18 +13,11 @@ | ||||
| // @noframes | ||||
| // ==/UserScript== | ||||
|  | ||||
| if (location.pathname == "/watch" && location.search.includes("&list=")){ | ||||
|     history.replaceState({}, document.title, location.search.replace(/&list=(.*)/, "")); | ||||
|     location.reload(); | ||||
| function redirectPlaylist() { | ||||
| 	if (location.pathname === "/watch" && location.search.includes("&list=")) { | ||||
| 		location.replace(location.href.replace(/&list=(.*)/, "")); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| document.addEventListener("spfclick", function(e){ | ||||
|     var url = e.detail.url; | ||||
|      | ||||
|     if (url.includes("youtube.com/watch?") && url.includes("&list=")){ | ||||
|         // forces a normal page load | ||||
|         e.preventDefault(); | ||||
|         e.stopPropagation(); | ||||
|         e.stopImmediatePropagation(); | ||||
|     } | ||||
| }, true); | ||||
| redirectPlaylist(); | ||||
| document.addEventListener("yt-navigate-start", redirectPlaylist); | ||||
|   | ||||
							
								
								
									
										23
									
								
								YouTube/RedirectShorts.user.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								YouTube/RedirectShorts.user.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | ||||
| // ==UserScript== | ||||
| // @name         Redirect YouTube Shorts | ||||
| // @description  Redirects YouTube shorts to normal video URLs. | ||||
| // @version      1 | ||||
| // @license      MPL-2.0 | ||||
| // @namespace    https://chylex.com | ||||
| // @homepageURL  https://github.com/chylex/Userscripts | ||||
| // @supportURL   https://github.com/chylex/Userscripts/issues | ||||
| // @include      https://youtube.com/* | ||||
| // @include      https://*.youtube.com/* | ||||
| // @run-at       document-start | ||||
| // @grant        none | ||||
| // @noframes | ||||
| // ==/UserScript== | ||||
|  | ||||
| function redirectShort() { | ||||
| 	if (location.pathname.startsWith("/shorts/")) { | ||||
| 		location.replace(location.href.replace("/shorts/", "/watch?v=")); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| redirectShort(); | ||||
| document.addEventListener("yt-navigate-start", redirectShort); | ||||
		Reference in New Issue
	
	Block a user