YouTube Toggle Description Button and collapse on empty space click

Displays a "Toggle Description" button to the right. Also, when the description is expanded, clicking on an empty part of the description will collapse it.

  1. // ==UserScript==
  2. // @name YouTube Toggle Description Button and collapse on empty space click
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.12
  5. // @description Displays a "Toggle Description" button to the right. Also, when the description is expanded, clicking on an empty part of the description will collapse it.
  6. // @match https://www.youtube.com/*
  7. // @author ChatGPT
  8. // @license MIT
  9. // ==/UserScript==
  10.  
  11. (function() {
  12. 'use strict';
  13.  
  14. // Function that simulates a click on the built-in expand/collapse buttons.
  15. function toggleDescription() {
  16. const descriptionContainer = document.querySelector('#description-inline-expander');
  17. if (!descriptionContainer) return;
  18. const collapseButton = descriptionContainer.querySelector('#collapse');
  19. const expandButton = descriptionContainer.querySelector('#expand');
  20. if (collapseButton && !collapseButton.hidden) {
  21. collapseButton.click();
  22. } else if (expandButton && !expandButton.hidden) {
  23. expandButton.click();
  24. }
  25. }
  26.  
  27. // Create a toggle button styled similarly to YouTube’s native button.
  28. // We use flex properties to dock the button to the right.
  29. function createStyledToggleButton() {
  30. const btn = document.createElement('tp-yt-paper-button');
  31. btn.id = 'subtle-toggle-button';
  32. btn.textContent = 'Toggle Description';
  33. btn.className = 'style-scope tp-yt-paper-button button ytd-text-inline-expander';
  34. btn.setAttribute('elevation', '0');
  35. btn.setAttribute('role', 'button');
  36.  
  37. btn.style.cssText = `
  38. color: var(--ytd-text-inline-expander-button-color, var(--yt-spec-text-secondary));
  39. margin: 0;
  40. padding: 0;
  41. font-family: "Roboto", "Arial", sans-serif;
  42. font-size: 1.4rem;
  43. line-height: 2rem;
  44. font-weight: 500;
  45. text-transform: none;
  46. background: transparent;
  47. border: none;
  48. cursor: pointer;
  49. white-space: pre;
  50. text-align: right;
  51. margin-left: auto;
  52. `;
  53.  
  54. // Clicking the button toggles the description.
  55. btn.addEventListener('click', toggleDescription);
  56. return btn;
  57. }
  58.  
  59. // Insert the toggle button into the info container and force flex layout.
  60. function addToggleButton() {
  61. const infoContainer = document.querySelector('#info-container');
  62. if (!infoContainer) return;
  63.  
  64. // Force the container into a flex layout.
  65. infoContainer.style.setProperty('display', 'flex', 'important');
  66. infoContainer.style.setProperty('align-items', 'center', 'important');
  67.  
  68. // Avoid duplicates.
  69. if (document.querySelector('#subtle-toggle-button')) return;
  70. const toggleButton = createStyledToggleButton();
  71. infoContainer.appendChild(toggleButton);
  72. }
  73.  
  74. // Add an event listener to the description expander so that when it is expanded,
  75. // clicking on any non-interactive (empty) space collapses the description.
  76. function addDescriptionCollapseListener() {
  77. const descExpander = document.querySelector('#description-inline-expander');
  78. if (!descExpander) return;
  79. // Only add once.
  80. if (descExpander.dataset.collapseListenerAdded) return;
  81. descExpander.addEventListener('click', function(e) {
  82. // Check if the description is expanded (collapse button is visible)
  83. const collapseButton = descExpander.querySelector('#collapse');
  84. if (collapseButton && !collapseButton.hidden) {
  85. // Only act if you did not click on an interactive element (like a link or a button).
  86. if (!e.target.closest('a, button, tp-yt-paper-button')) {
  87. collapseButton.click();
  88. // Prevent any other click handling (for example, YouTube’s own expand logic).
  89. e.stopPropagation();
  90. }
  91. }
  92. });
  93. descExpander.dataset.collapseListenerAdded = 'true';
  94. }
  95.  
  96. // Combine the toggle button and the collapse listener setup.
  97. function addToggleButtonAndCollapseListener() {
  98. addToggleButton();
  99. // Comment below line to disable empty space collapse behaviour
  100. addDescriptionCollapseListener();
  101. }
  102.  
  103. // Use a persistent MutationObserver to re-add the button and listener if needed.
  104. const observer = new MutationObserver(() => {
  105. addToggleButtonAndCollapseListener();
  106. });
  107. observer.observe(document.body, { childList: true, subtree: true });
  108. })();