Hummingbird 10 Point Ratings

Converts Hummingbird ratings to a 10 point scale

当前为 2016-09-04 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Hummingbird 10 Point Ratings
  3. // @namespace https://greasyfork.org/users/649
  4. // @version 1.5.11
  5. // @description Converts Hummingbird ratings to a 10 point scale
  6. // @author Adrien Pyke
  7. // @match *://hummingbird.me/*
  8. // @require https://greasyfork.org/scripts/5679-wait-for-elements/code/Wait%20For%20Elements.js?version=122976
  9. // @grant none
  10. // ==/UserScript==
  11.  
  12. (function() {
  13. 'use strict';
  14.  
  15. var SCRIPT_NAME = 'Hummingbird 10 Point';
  16. var ANIME_REGEX = /^https?:\/\/hummingbird\.me\/(?:anime|manga)\/[^\/]+\/?(?:\?.*)?$/;
  17. var REVIEW_REGEX = /^https?:\/\/hummingbird\.me\/(?:anime|manga)\/[^\/]+\/reviews\/[^\/]+\/?(?:\?.*)?$/;
  18. var SETTINGS_REGEX = /^https?:\/\/hummingbird\.me\/settings/;
  19.  
  20. var Util = {
  21. log: function() {
  22. var args = [].slice.call(arguments);
  23. args.unshift('%c' + SCRIPT_NAME + ':', 'font-weight: bold;color: #233c7b;');
  24. console.log.apply(console, args);
  25. },
  26. q: function(query, context) {
  27. return (context || document).querySelector(query);
  28. },
  29. qq: function(query, context) {
  30. return [].slice.call((context || document).querySelectorAll(query));
  31. }
  32. };
  33.  
  34. var convertWidget = function(widget) {
  35. var select = document.createElement('select');
  36. select.classList.add('ember-view', 'ember-select', 'form-control', 'tenpoint');
  37.  
  38. var addOption = function(value, text) {
  39. var option = document.createElement('option');
  40. option.classList.add('ember-view');
  41. option.setAttribute('value', value);
  42. option.textContent = text;
  43. select.appendChild(option);
  44. return option;
  45. };
  46.  
  47. addOption(0, 'No Rating');
  48. for (var i = 1; i <= 10; i++) {
  49. addOption(i, i);
  50. }
  51.  
  52. var rating = (Util.qq('.fa-star', widget).length * 2) + Util.qq('.fa-star-half-o', widget).length;
  53. select.value = rating;
  54.  
  55. var clickWidget = function(num) {
  56. var star = Util.q('span:nth-of-type(' + Math.ceil(num / 2) + ')', widget);
  57. var bounds = star.getBoundingClientRect();
  58. var pageY = bounds.top;
  59. var pageX = bounds.left + bounds.width / 2;
  60. if (num % 2 === 0) {
  61. pageX += 1;
  62. } else {
  63. pageX -= 1;
  64. }
  65.  
  66. var e = document.createEvent('HTMLEvents');
  67. e.initEvent('click', true);
  68. e.pageX = pageX;
  69. e.pageY = pageY;
  70. star.dispatchEvent(e);
  71. };
  72.  
  73. select.onchange = function(e) {
  74. if (select.value === rating) return;
  75. if (select.value === '0') {
  76. clickWidget(rating);
  77. } else {
  78. clickWidget(select.value);
  79. }
  80. rating = select.value;
  81. };
  82.  
  83. widget.style.visibility = 'hidden';
  84. widget.style.position = 'fixed';
  85. widget.style.top = 0;
  86. widget.style.left = 0;
  87. widget.parentNode.appendChild(select);
  88. };
  89.  
  90. var convertRatingsList = function(elem) {
  91. var origRatingNode = Util.q('span', elem);
  92. if (origRatingNode) {
  93. origRatingNode.style.display = 'none';
  94.  
  95. var node = document.createElement('span');
  96. elem.appendChild(node);
  97.  
  98. var updateRating = function() {
  99. if (elem.classList.contains('not-rated')) {
  100. node.textContent = '—';
  101. } else {
  102. node.textContent = parseInt(parseFloat(origRatingNode.textContent) * 2);
  103. }
  104. };
  105. updateRating();
  106.  
  107. var fullEntry = elem.parentNode.parentNode.parentNode;
  108. fullEntry.addEventListener('click', function(e) {
  109. if (!e.target.dataset.reactid && (e.target.classList.contains('fa') || e.target.classList.contains('icon-container'))) {
  110. setTimeout(updateRating, 0);
  111. }
  112. });
  113. }
  114. };
  115. waitForElems('.library-table .list-item-score', convertRatingsList);
  116.  
  117. var convertAnimePage = function() {
  118. waitForElems('.hb-score > h3 > .highlight', function(score) {
  119. score.style.display = 'none';
  120. var newScore = Util.q('.tenpoint', score.parentNode);
  121. if (!newScore) {
  122. newScore = document.createElement('span');
  123. newScore.classList = score.classList;
  124. newScore.classList.add('tenpoint');
  125. score.parentNode.appendChild(newScore);
  126. }
  127. newScore.textContent = (parseFloat(score.textContent) * 2).toFixed(2);
  128.  
  129. var columns = Util.qq('.community-rating-wrapper > li');
  130. columns.forEach(function(column) {
  131. var tooltipData = column.dataset.tooltip.split(' ');
  132. tooltipData[tooltipData.length - 1] = parseInt(tooltipData[tooltipData.length - 1] * 2);
  133. var tooltip = tooltipData.join(' ');
  134. column.dataset.tooltip = tooltip;
  135. column.setAttribute('title', tooltip);
  136. });
  137.  
  138. var stars = Util.qq('.lowest-rating > .fa-star-half-o, .highest-rating > .fa-star');
  139. if (stars.length > 0) {
  140. stars.forEach(function(star) {
  141. star.remove();
  142. });
  143. var lowestRating = Util.q('.lowest-rating');
  144. lowestRating.innerHTML = 0 + lowestRating.innerHTML;
  145. var highestRating = Util.q('.highest-rating');
  146. highestRating.innerHTML += 10;
  147. }
  148.  
  149. var widget = Util.q('.awesome-rating-widget');
  150. if (widget) {
  151. var oldSelect = Util.q('select.tenpoint', widget.parentNode);
  152. if (oldSelect) oldSelect.remove();
  153. convertWidget(widget);
  154. }
  155. }, true);
  156. };
  157. waitForUrl(ANIME_REGEX, convertAnimePage);
  158.  
  159. waitForElems('.awesome-rating-widget', function(widget) {
  160. if (!location.href.match(SETTINGS_REGEX)) {
  161. if (widget.style.visibility !== 'hidden') {
  162. // if not already converted
  163. convertWidget(widget);
  164. }
  165. }
  166. });
  167.  
  168. var convertReviewPage = function() {
  169. waitForElems('.review-breakdown', function(review) {
  170. var verdict = review.querySelector('.score-block');
  171. var rating = parseFloat(Util.q('.score', verdict).textContent) + parseFloat(Util.q('.decimal-score', verdict).textContent);
  172. verdict.innerHTML = '';
  173. var newScore = document.createElement('h1');
  174. newScore.classList.add('score');
  175. newScore.textContent = parseInt(rating * 2);
  176. verdict.appendChild(newScore);
  177.  
  178. var breakdown = Util.qq('.dec-score > strong', review);
  179. breakdown.forEach(function(entry) {
  180. entry.textContent = parseInt(parseFloat(entry.textContent) * 2);
  181. });
  182. }, true);
  183. };
  184. waitForUrl(REVIEW_REGEX, convertReviewPage);
  185.  
  186. var convertUserReviews = function(stars) {
  187. var score = Util.qq('.fa-star', stars).length * 2 + Util.qq('.fa-star-half-o', stars).length;
  188. stars.innerHTML = score;
  189. stars.style.fontWeight = 'bold';
  190. };
  191. waitForElems('.user-review-listing .review-stars', convertUserReviews);
  192. })();