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-28 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Change YouTube Leftbar Subscription Links To Channel/User Video Page
  3. // @namespace ChangeYouTubeLeftbarSubscriptionLinksToChannelUserVideoPage
  4. // @version 1.1.5
  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 && (x = x.guideEntryRenderer.navigationEndpoint)) {
  31. x.commandMetadata.webCommandMetadata.url += "/videos";
  32. if (x.webNavigationEndpointData) x.webNavigationEndpointData.url += "/videos";
  33. }
  34. });
  35. } else if (w = w.guideEntryRenderer.navigationEndpoint) {
  36. w.commandMetadata.webCommandMetadata.url += "/videos";
  37. if (w.webNavigationEndpointData) w.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. w = v[vc].guideCollapsibleEntryRenderer;
  46. l = v.splice(0, vc);
  47. c = -1;
  48. if (w) {
  49. (w = w.expandableItems).some(function(e, i) {
  50. if (!e.guideEntryRenderer.badges) {
  51. c = i;
  52. return true;
  53. }
  54. });
  55. l.push.apply(l, w.splice(0, c));
  56. }
  57. c = [];
  58. for (i = l.length - 1; i >= 0; i--) {
  59. if (l[i].guideEntryRenderer.count) {
  60. if (vc--) {
  61. v.unshift(l.splice(i, 1)[0]);
  62. } else c.unshift(l.splice(i, 1)[0]);
  63. }
  64. }
  65. c.push.apply(c, l);
  66. if (vc) {
  67. l = c.splice(0, vc);
  68. l.unshift.apply(l, [v.length - 1, 0]);
  69. v.splice.apply(v, l);
  70. }
  71. if (w) w.unshift.apply(w, c);
  72. }
  73. }
  74. });
  75. return true;
  76. }
  77. return false;
  78. }
  79.  
  80. var ht1 = 0, ht2 = 0;
  81.  
  82. (function chkStatic(ev) {
  83. clearTimeout(ht1);
  84. if (!patchGuide(window.ytInitialGuideData)) {
  85. ht1 = setTimeout(chkStatic, 0);
  86. }
  87. })();
  88.  
  89. (function chkSpf() {
  90. clearTimeout(ht2);
  91. if (window.spf && spf.request && !spf.request_cysl) {
  92. spf.request_cysl = spf.request;
  93. spf.request = function(a, b) {
  94. if (b && b.onDone) {
  95. var onDone_ = b.onDone;
  96. b.onDone = function(response) {
  97. if (response && (/\/guide_ajax\?/).test(response.url) && response.response && response.response.response) {
  98. patchGuide(response.response.response);
  99. }
  100. return onDone_.apply(this, arguments);
  101. };
  102. return this.request_cysl.apply(this, arguments);
  103. }
  104. };
  105. return;
  106. }
  107. ht2 = setTimeout(chkSpf, 0);
  108. })();
  109.  
  110. addEventListener("load", function() {
  111. clearTimeout(ht1);
  112. clearTimeout(ht2);
  113. });