Youtube Playlists Sorted Alphabetically

When you click on "+ Add to" (for adding a new video to a playlist) YouTube displays the playlists -by default- in a strange order: beginning with the one selected last. This script arranges your playlists alphabetically, making it easier for you to find the one you are looking for.

  1. // ==UserScript==
  2. // @name Youtube Playlists Sorted Alphabetically
  3. // @namespace http://www.pbworks.net
  4. // @description When you click on "+ Add to" (for adding a new video to a playlist) YouTube displays the playlists -by default- in a strange order: beginning with the one selected last. This script arranges your playlists alphabetically, making it easier for you to find the one you are looking for.
  5. // @author Paolo Brocco
  6. // @homepage http://www.pbworks.net
  7. // @copyright 2012+, Paolo Brocco (http://www.pbworks.net)
  8. // @license GPL version 3 or any later version; http://www.gnu.org/copyleft/gpl.html
  9. // @version 2015.07.09
  10. // @include http://www.youtube.com/*
  11. // @include https://www.youtube.com/*
  12. // @uso:script 123272
  13. // ==/UserScript==
  14.  
  15. /*** DOCUMENT READY: triggers (buttons) with added calls to this script functions ***/
  16.  
  17. document.addEventListener('DOMContentLoaded', function() {
  18. //here begins everything
  19.  
  20. //This is the "Add to" button
  21. document.querySelector('#watch8-secondary-actions > div.yt-uix-menu.yt-uix-videoactionmenu > button').setAttribute('onclick', ';initSortLists();return false;');
  22. }, false);
  23.  
  24. /*** INIT FUNCTIONS: logic to decide when to activate the sorting ***/
  25.  
  26. unsafeWindow.initSortLists = function(){
  27.  
  28. //this function checks if the menu is ready (ready I mean: if the ul list has children (li) (youtube populates the list via ajax, then shows it) ):
  29. //if ready: call sortLists()
  30. //else: wait for 100 ms
  31. var container = document.querySelector('#addto-list-panel > div.playlists.yt-uix-scroller > ul');
  32.  
  33. if(typeof container !== 'undefined' && container != null)
  34. {
  35. //unsafeWindow.console.log('the menu is ready!');
  36. if (!container.classList.contains('sorted'))
  37. {
  38. var lists = container.querySelectorAll('li');
  39.  
  40. if (lists.length > 0) {
  41. //unsafeWindow.console.log('playlists arrived, sorting them.');
  42. unsafeWindow.sortLists();
  43. }
  44. else {
  45. setTimeout('initSortLists()', 100);
  46. }
  47. }
  48. else
  49. {
  50. //unsafeWindow.console.log('playlists already sorted ;)');
  51. }
  52. return false;
  53. }
  54. else
  55. {
  56. //unsafeWindow.console.log('waiting 100 ms...');
  57. setTimeout('initSortLists()', 100);
  58. }
  59. }
  60.  
  61. /*** SORTING FUNCTIONS ***/
  62.  
  63. unsafeWindow.sortLists = function(){
  64. //this function does what we want, meaning the sorting of the playlists, alphabetically
  65. //unsafeWindow.console.log('doing the magic!');
  66.  
  67. var oldList = document.querySelector('#addto-list-panel > div.playlists.yt-uix-scroller > ul');
  68.  
  69. var listParent = oldList.parentNode;
  70.  
  71. var plists = [];
  72. var lTitle, lElement, newList;
  73.  
  74. var lists = document.querySelectorAll('#addto-list-panel > div.playlists.yt-uix-scroller > ul li');
  75.  
  76. [].forEach.call(lists, function(li) {
  77.  
  78. unsafeWindow.console.log('a list');
  79.  
  80. lTitle = li.getAttribute('data-item-name');
  81. lElement = li;
  82.  
  83. plists.push(listData(lTitle, li));
  84. });
  85.  
  86. plists.sort(SortByTitle);
  87.  
  88. newList = document.createElement('ul');
  89. newList.setAttribute('role', 'menu');
  90. newList.setAttribute('tabindex', '0');
  91. newList.setAttribute('class', 'yt-uix-kbd-nav yt-uix-kbd-nav-list sorted');
  92. for (p in plists)
  93. {
  94. newList.appendChild(plists[p].lElement);
  95. }
  96. listParent.replaceChild(newList, oldList);
  97. }
  98.  
  99. /*** HELPERS ***/
  100.  
  101. //This will sort an array
  102. function SortByTitle(a, b){
  103. var aName = a.title.toLowerCase();
  104. var bName = b.title.toLowerCase();
  105. return ((aName < bName) ? -1 : ((aName > bName) ? 1 : 0));
  106. }
  107.  
  108. //function to populate lists data array
  109. function listData(title, lElement) {
  110. return {
  111. title: title,
  112. lElement: lElement
  113. }
  114. }