Youtube Related Video Ratings

Shows ratings of related videos on Youtube, and changes ratings bar back to green/red.

当前为 2014-12-10 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Youtube Related Video Ratings
  3. // @description Shows ratings of related videos on Youtube, and changes ratings bar back to green/red.
  4. // @namespace https://greasyfork.org/users/2329-killerbadger
  5. // @version 0.1.2
  6. // @match http://www.youtube.com/*
  7. // @match https://www.youtube.com/*
  8. // ==/UserScript==
  9.  
  10. /* Borrowed/adapted code from YouTube Link Cleaner by tfr
  11. * "Dieses Skript steht unter CC0 / This script is licensed under CC0:
  12. * http://creativecommons.org/publicdomain/zero/1.0/deed.de
  13. * http://creativecommons.org/publicdomain/zero/1.0/deed.en" */
  14. LinkCount = 0;
  15. function ChangeLinks() {
  16. if(LinkCount != window.document.links.length) {
  17. for (var i = 0; i < window.document.links.length; i++) {
  18. /* Do not use redirect pages, disable AJAX on links */
  19. window.document.links[i].className = window.document.links[i].className.replace(/(yt-uix-redirect-link|spf-link)/g, "");
  20. }
  21. LinkCount = window.document.links.length;
  22. }
  23. }
  24. ChangeLinks();
  25. window.setInterval(ChangeLinks, 1000);
  26. /* End of borrowed/adapted code */
  27.  
  28. GM_addStyle(".video-time { margin-bottom: 4px;} .yt-uix-simple-thumb-related > img {margin-bottom: -27px !important;} a.related-video { padding-bottom: 11px !important; margin-bottom: -11px !important; } .lsLines { opacity: 0; } .lsLines:hover { opacity: .6; } .channels-browse-content-grid .channels-content-item { height: 167px } .yt-thumb-default-288 + span + button + div > .lsLines { background-size: 288px 4px; } .yt-thumb-default-194 + span + button + div > .lsLines { background-size: 194px 4px; } .yt-thumb-default-185 + span + button + div > .lsLines, .yt-thumb-feed-185 + span + span + div .lsLines { background-size: 185px 4px; } .yt-thumb-default-160 + img + span + div > .lsLines { background-size: 160px 4px; } .yt-thumb-default-40 + span + span + span + span + div .lsLines { background-size: 157px 4px; } .yt-thumb-default-106 + span + button + div > .lsLines { background-size: 106px 4px; } .yt-thumb-default-138 + span + button + div > .lsLines { background-size: 138px 4px; } .yt-thumb-default-120 + span + button + div > .lsLines, .yt-thumb-default-224 + span + div > .lsLines { background-size: 120px 4px; } .yt-thumb-default-76 + span + span + span + div .lsLines { background-size: 76px 4px; } .yt-thumb-default-64 + div > .lsLines { background-size: 64px 4px; } .feed-item-thumb.watched .ux-thumb-wrap {opacity: 1 !important;} .ux-thumb {background-color: white !important;} .feed-item-thumb.watched .ux-thumb-wrap img {opacity: .4 !important;} .feed-item-thumb.watched .ux-thumb-wrap img:hover {opacity: 1 !important;} .feed-thumb-watched {opacity: .5 !important;} .video-response .video-extras-sparkbarks {width: 26% !important;} .video-extras-sparkbar-likes {border-right: 0px !important}");
  29.  
  30. if (document.getElementById("watch7-views-info")) {
  31. document.getElementsByClassName("video-extras-sparkbar-likes")[0].style.background = "#0b2";
  32. document.getElementsByClassName("video-extras-sparkbar-dislikes")[0].style.background = "#C00";
  33. }
  34. var loaded = {};
  35. var containerName="yt-thumb-default";
  36. var containerName2="video-time";
  37. loaded[""] = true;
  38. window.addEventListener (
  39. 'scroll',
  40. function (e) {
  41. iterateClips(document.getElementsByClassName(containerName));
  42. iterateClips(document.getElementsByClassName(containerName2));
  43. },
  44. false);
  45. var wm = document.getElementById("watch-more-related");
  46. if (wm) {
  47. // On "Load More Suggestions" button click
  48. wm.addEventListener (
  49. 'DOMNodeInserted',
  50. function (e) {
  51. iterateClips(e.target.getElementsByClassName(containerName));
  52. iterateClips(e.target.getElementsByClassName(containerName2));
  53. },
  54. false);
  55. }
  56.  
  57. // starts here
  58. iterateClips(document.getElementsByClassName(containerName));
  59. iterateClips(document.getElementsByClassName(containerName2));
  60.  
  61. function iterateClips(clips)
  62. {
  63. if (clips)
  64. {
  65. for (var i=0; i<clips.length; ++i)
  66. if (isVisible(clips[i]))
  67. requestRating(clips[i]);
  68. }
  69. }
  70.  
  71. function requestRating(box)
  72. {
  73. var id = getVideoId(box);
  74.  
  75. if (loaded[id])
  76. return;
  77.  
  78. loaded[id] = true;
  79. setTimeout( function() {
  80. GM_xmlhttpRequest({
  81. method: 'GET',
  82. url: "http://gdata.youtube.com/feeds/api/videos/" + id + "?v=2&alt=json&fields=yt:rating",
  83. onload: function(response)
  84. {
  85. if (response.status == 200)
  86. {
  87. var rsp = eval( '(' + response.responseText + ')' );
  88. if (rsp && rsp.entry && rsp.entry.yt$rating)
  89. attachBar(box, parseInt(rsp.entry.yt$rating.numLikes),
  90. parseInt(rsp.entry.yt$rating.numDislikes));
  91. }
  92. else
  93. delete loaded[id]; // give it a chance to reload while scrolling
  94. }
  95. });
  96. }, 0);
  97. }
  98.  
  99. function getVideoId(box)
  100. {
  101. var anchor=box.parentNode.parentNode;
  102. var isAnchorFound = 2;
  103. while (anchor && anchor.tagName != undefined)
  104. {
  105. if (anchor.tagName.toLowerCase()=="a")
  106. break;
  107. anchor = anchor.parentNode;
  108. --isAnchorFound;
  109. if (0==isAnchorFound)
  110. break;
  111. }
  112. if ( isAnchorFound>0 )
  113. {
  114. var href = anchor.getAttribute("href");
  115. if (href)
  116. {
  117. var id = href.replace(/.*v=([^&]*).*/, "$1");
  118. if (id.length<href.length)
  119. return id;
  120. }
  121. }
  122. return "";
  123. }
  124. function attachBar(videoThumb, likes, dislikes)
  125. {
  126. var total = likes + dislikes;
  127.  
  128. if (total > 0)
  129. {
  130. var ratingDiv = document.createElement("div");
  131. ratingDiv.setAttribute("class", "video-extras-sparkbarks");
  132. ratingDiv.setAttribute("style", "position: relative; top: 1px;" );
  133. ratingDiv.setAttribute("title", likes + " likes, " + dislikes + " dislikes");
  134.  
  135. var likesDiv = document.createElement("div");
  136. likesDiv.setAttribute("class", "video-extras-sparkbar-likes");
  137. likesDiv.setAttribute("style", "height: 4px; width: "+(100*likes)/total+"%; background: #0b2;");
  138.  
  139. var dislikesDiv = document.createElement("div");
  140. dislikesDiv.setAttribute("class", "video-extras-sparkbar-dislikes");
  141. dislikesDiv.setAttribute("style", "height: 4px; width: "+(100*dislikes)/total+"%;"+"background: #C00;");
  142.  
  143. ratingDiv.appendChild(likesDiv);
  144. ratingDiv.appendChild(dislikesDiv);
  145. videoThumb.parentNode.parentNode.appendChild(ratingDiv);
  146. videoThumb.parentNode.appendChild(ratingDiv);
  147. //videoThumb.appendChild(ratingDiv);
  148.  
  149. // fixing time element position to be inside of the thumb image
  150. var spans = videoThumb.parentNode.parentNode.getElementsByTagName("span");
  151. for (var i=0; i<spans.length; ++i )
  152. if (spans[i].getAttribute("class")=="video-time")
  153. {
  154. spans[i].style.bottom = "6px";
  155. break;
  156. }
  157. }
  158. }
  159.  
  160. function isVisible ( el )
  161. {
  162. var top = el.offsetTop;
  163. var left = el.offsetLeft;
  164. var width = el.offsetWidth;
  165. var height = el.offsetHeight;
  166.  
  167. while(el.offsetParent) {
  168. el = el.offsetParent;
  169. top += el.offsetTop;
  170. left += el.offsetLeft;
  171. }
  172. return (
  173. top < (window.pageYOffset + window.innerHeight) &&
  174. left < (window.pageXOffset + window.innerWidth) &&
  175. (top + height) > window.pageYOffset &&
  176. (left + width) > window.pageXOffset
  177. );
  178. }