Youtube clickbait capitalization fix

Makes all Youtube video titles consistent, only the first letter of the title is uppercase

  1. // ==UserScript==
  2. // @name Youtube clickbait capitalization fix
  3. // @namespace Youtube
  4. // @version 2023-12-18
  5. // @match https://*.youtube.com
  6. // @description Makes all Youtube video titles consistent, only the first letter of the title is uppercase
  7. // @author You
  8. // @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
  9. // @grant none
  10. // @license MIT
  11. // ==/UserScript==
  12.  
  13.  
  14. function formatTitle(element) {
  15. // Get the title attribute of the parent element
  16. let titleText = element.parentNode.getAttribute('title');
  17.  
  18. // Split the title into words
  19. let words = titleText.split(' ');
  20.  
  21. // Capitalize the first word and make the rest lowercase
  22. words = words.map((word, index) => {
  23. if (index === 0) {
  24. return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
  25. } else {
  26. return word.toLowerCase();
  27. }
  28. });
  29.  
  30. // Join the words back together
  31. let formattedTitle = words.join(' ');
  32.  
  33. // Set the text content of the element to the formatted title
  34. element.textContent = formattedTitle;
  35. }
  36.  
  37. function observeTitleChanges() {
  38. // Get all elements with the tag <yt-formatted-string> and the id #video-title
  39. let titleElements = document.querySelectorAll('yt-formatted-string#video-title');
  40.  
  41. // Create a MutationObserver instance
  42. let observer = new MutationObserver((mutations) => {
  43. mutations.forEach((mutation) => {
  44. if (mutation.type === 'attributes' && mutation.attributeName === 'title') {
  45. formatTitle(mutation.target.querySelector('yt-formatted-string#video-title'));
  46. }
  47. });
  48. });
  49.  
  50. // Start observing each parent element for changes in its title attribute
  51. titleElements.forEach(titleElement => {
  52. observer.observe(titleElement.parentNode, { attributes: true, attributeFilter: ['title'] });
  53. formatTitle(titleElement);
  54. });
  55. }
  56.  
  57.  
  58.  
  59. (function() {
  60. 'use strict';
  61.  
  62. // Set up a timer to check continuously if the titles have loaded
  63. let checkInterval = setInterval(() => {
  64. if (document.querySelectorAll('yt-chip-cloud-chip-renderer').length > 5) {
  65. clearInterval(checkInterval);
  66. observeTitleChanges();
  67. }
  68. }, 500);
  69. })();