Change YouTube Leftbar Subscription Links To Channel/User Video Page

Change YouTube leftbar's subscription links to channel/user video page. This script can optionally also move the links to top of the list if it has new uploaded videos. Both features can be enabled/disabled. For new YouTube layout only.

当前为 2018-02-25 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Change YouTube Leftbar Subscription Links To Channel/User Video Page
  3. // @namespace ChangeYouTubeLeftbarSubscriptionLinksToChannelUserVideoPage
  4. // @version 1.1.4
  5. // @license AGPL v3
  6. // @description Change YouTube leftbar's subscription links to channel/user video page. This script can optionally also move the links to top of the list if it has new uploaded videos. Both features can be enabled/disabled. For new YouTube layout only.
  7. // @author jcunews
  8. // @match *://www.youtube.com/*
  9. // @grant none
  10. // @run-at document-start
  11. // ==/UserScript==
  12.  
  13. //===== Configuration Start ===
  14.  
  15. var changeLinksURL = true;
  16. var moveLinksToTop = true;
  17.  
  18. //===== Configuration End ===
  19.  
  20. function patchGuide(guide) {
  21. if (guide && !guide.cysl_done) {
  22. guide.cysl_done = 1;
  23. guide.items.forEach(function(v, vc, l, w, c, i) {
  24. if (v.guideSubscriptionsSectionRenderer) {
  25. //change links' URL
  26. if (changeLinksURL) {
  27. v.guideSubscriptionsSectionRenderer.items.forEach(function(w) {
  28. if (w.guideCollapsibleEntryRenderer) {
  29. w.guideCollapsibleEntryRenderer.expandableItems.forEach(function(x) {
  30. if (x.guideEntryRenderer.badges) {
  31. x.guideEntryRenderer.navigationEndpoint.commandMetadata.webCommandMetadata.url += "/videos";
  32. x.guideEntryRenderer.navigationEndpoint.webNavigationEndpointData.url += "/videos";
  33. }
  34. });
  35. } else {
  36. w.guideEntryRenderer.navigationEndpoint.commandMetadata.webCommandMetadata.url += "/videos";
  37. w.guideEntryRenderer.navigationEndpoint.webNavigationEndpointData.url += "/videos";
  38. }
  39. });
  40. }
  41. //move links with new uploads to top
  42. if (moveLinksToTop) {
  43. v = v.guideSubscriptionsSectionRenderer.items;
  44. vc = v.length - 1;
  45. if (w = v[vc].guideCollapsibleEntryRenderer) {
  46. l = v.splice(0, vc);
  47. c = -1;
  48. (w = w.expandableItems).some(function(e, i) {
  49. if (!e.guideEntryRenderer.badges) {
  50. c = i;
  51. return true;
  52. }
  53. });
  54. l.push.apply(l, w.splice(0, c));
  55. c = [];
  56. for (i = l.length - 1; i >= 0; i--) {
  57. if (l[i].guideEntryRenderer.count) {
  58. if (vc--) {
  59. v.unshift(l.splice(i, 1)[0]);
  60. } else c.unshift(l.splice(i, 1)[0]);
  61. }
  62. }
  63. c.push.apply(c, l);
  64. if (vc) {
  65. l = c.splice(0, vc);
  66. l.unshift.apply(l, [v.length - 1, 0]);
  67. v.splice.apply(v, l);
  68. }
  69. w.unshift.apply(w, c);
  70. }
  71. }
  72. }
  73. });
  74. return true;
  75. }
  76. return false;
  77. }
  78.  
  79. var ht1 = 0, ht2 = 0;
  80.  
  81. (function chkStatic(ev) {
  82. clearTimeout(ht1);
  83. if (!patchGuide(window.ytInitialGuideData)) {
  84. ht1 = setTimeout(chkStatic, 0);
  85. }
  86. })();
  87.  
  88. (function chkSpf() {
  89. clearTimeout(ht2);
  90. if (window.spf && spf.request && !spf.request_cysl) {
  91. spf.request_cysl = spf.request;
  92. spf.request = function(a, b) {
  93. if (b && b.onDone) {
  94. var onDone_ = b.onDone;
  95. b.onDone = function(response) {
  96. if (response && (/\/guide_ajax\?/).test(response.url) && response.response && response.response.response) {
  97. patchGuide(response.response.response);
  98. }
  99. return onDone_.apply(this, arguments);
  100. };
  101. return this.request_cysl.apply(this, arguments);
  102. }
  103. };
  104. return;
  105. }
  106. ht2 = setTimeout(chkSpf, 0);
  107. })();
  108.  
  109. addEventListener("load", function() {
  110. clearTimeout(ht1);
  111. clearTimeout(ht2);
  112. });