|
// ==UserScript== |
|
// @name YouTube Smart Fucking Title Modifier v2.1 |
|
// @namespace http://tampermonkey.net/ |
|
// @version 2.1 |
|
// @description Inserts "fucking" intelligently in YouTube titles, handles character sequences like "why", "the", "this", respects all caps, injects only once after the first word |
|
// @author Alex |
|
// @match https://www.youtube.com/* |
|
// @grant none |
|
// @run-at document-idle |
|
// ==/UserScript== |
|
|
|
(function() { |
|
'use strict'; |
|
|
|
const connectors = ['i', 'in', 'on', 'at', 'for', 'with', 'and', 'but', 'so', 'because', 'just']; |
|
const charSequenceRules = [ |
|
{ seq: ['w','h','y'], inject: ' The Fuck' }, // "why" sequence |
|
{ seq: ['t','h','e'], inject: ' Fucking' }, // "the" sequence |
|
{ seq: ['t','h','i','s'], inject: ' Fucking' } // "this" sequence |
|
]; |
|
|
|
function modifyTitles() { |
|
const titles = document.querySelectorAll('a#video-title span, h3 span, h1 span'); |
|
|
|
titles.forEach(titleEl => { |
|
if (!titleEl.innerText.trim() || titleEl.dataset.fucked) return; |
|
|
|
let originalText = titleEl.innerText.trim(); |
|
const isAllCaps = originalText === originalText.toUpperCase(); |
|
let words = originalText.split(/\s+/); |
|
|
|
let injected = false; |
|
|
|
// Character sequence rules (check first, inject only once) |
|
for (let rule of charSequenceRules) { |
|
let titleChars = originalText.replace(/\s+/g, '').toLowerCase(); |
|
let seq = rule.seq.map(c => c.toLowerCase()); |
|
let match = true; |
|
let pos = 0; |
|
|
|
for (let i = 0; i < seq.length; i++) { |
|
pos = titleChars.indexOf(seq[i], pos); |
|
if (pos === -1) { match = false; break; } |
|
pos++; |
|
} |
|
|
|
if (match) { |
|
let injectedWord = rule.inject; |
|
if (isAllCaps) injectedWord = injectedWord.toUpperCase(); |
|
|
|
// Insert after first connector if exists, else random but at least index 1 |
|
let insertIndex = words.findIndex(w => connectors.includes(w.toLowerCase())); |
|
if (insertIndex !== -1) insertIndex += 1; |
|
else insertIndex = 1 + Math.floor(Math.random() * (words.length - 1)); |
|
|
|
words.splice(insertIndex, 0, injectedWord.trim()); |
|
injected = true; |
|
break; // stop after first match |
|
} |
|
} |
|
|
|
if (!injected) { |
|
let insertIndex = words.findIndex(w => connectors.includes(w.toLowerCase())); |
|
if (insertIndex !== -1) insertIndex += 1; |
|
else insertIndex = 1 + Math.floor(Math.random() * (words.length - 1)); |
|
|
|
let injectedWord = (insertIndex >= words.length) |
|
? (isAllCaps ? 'YOU FUCK' : 'You Fuck') |
|
: (isAllCaps ? 'FUCKING' : 'Fucking'); |
|
|
|
words.splice(insertIndex, 0, injectedWord); |
|
} |
|
|
|
titleEl.textContent = words.join(' '); |
|
titleEl.dataset.fucked = 'true'; |
|
}); |
|
} |
|
|
|
modifyTitles(); |
|
const observer = new MutationObserver(modifyTitles); |
|
observer.observe(document.body, { childList: true, subtree: true }); |
|
})(); |