IMDB works#

Shows number of credited works after names on IMDB site

当前为 2017-01-24 提交的版本,查看 最新版本

  1. // ==UserScript==//
  2. // @name IMDB works#
  3. // @description Shows number of credited works after names on IMDB site
  4. // @match *://*.imdb.com/*
  5. // @version 1.0.5
  6. // @author wOxxOm
  7. // @namespace wOxxOm.scripts
  8. // @license MIT License
  9. // @grant GM_addStyle
  10. // @grant GM_xmlhttpRequest
  11. // @run-at document-start
  12. // @require https://gf.qytechs.cn/scripts/12228/code/setMutationHandler.js
  13. // ==/UserScript==
  14.  
  15. var SELECTOR = 'a[href^="/name/nm"]';
  16. var CACHE_DURATION = 30 * 24 * 3600 * 1000; // 1 month
  17.  
  18. GM_addStyle(
  19. '.number-of-works, .number-of-works span { opacity: 0.5; transition: opacity .25s ease-in-out .25s; }' +
  20. '.number-of-works span:before { content: "/"; }' +
  21. '.number-of-works:hover { opacity: 1.0; }' +
  22. '.number-of-works:hover span { opacity: 1.0; }' +
  23. '.number-of-works:before { content: " ["; opacity: 0.5; }' +
  24. '.number-of-works:after { content: "]"; opacity: 0.5; }'
  25. );
  26.  
  27. process(document.querySelectorAll(SELECTOR));
  28. setMutationHandler(document, SELECTOR, process);
  29.  
  30. function process(links) {
  31. var now = Date.now();
  32. for (var link, i = 0; (link = links[i++]); ) {
  33. if (link.querySelector('img') ||
  34. !link.textContent.trim() ||
  35. link.nextElementSibling && link.nextElementSibling.matches('.number-of-works'))
  36. continue;
  37. var id = (link.pathname.match(/\/name\/nm(\d+)\/?$/) || [])[1];
  38. if (!id)
  39. continue;
  40. var cacheKey = 'works#' + id;
  41. var cache = (localStorage[cacheKey] || '').split('\t');
  42. if (cache.length == 2 && +cache[0] && cache[1]) {
  43. showWorksNum(link, cache[1]);
  44. var isFresh = +cache[0] > now;
  45. if (isFresh)
  46. continue;
  47. }
  48. doXHR({
  49. url: link.pathname,
  50. link: link,
  51. cacheKey: cacheKey,
  52. onload: parseNamePage,
  53. });
  54. }
  55. }
  56.  
  57. function showWorksNum(link, num, needsUpdate) {
  58. num = num.toString().replace(/\/(\d+)/, '<span>$1</span>');
  59. if (link.nextElementSibling && link.nextElementSibling.matches('.number-of-works')) {
  60. link.nextElementSibling.innerHTML = num;
  61. delete link.nextElementSibling.dataset.updating;
  62. } else {
  63. link.insertAdjacentHTML('afterend',
  64. '<span class="number-of-works"' +
  65. (needsUpdate ? ' data-updating' : '') + '>' +
  66. num +
  67. '</span>');
  68. }
  69. }
  70.  
  71. function parseNamePage(doc, options) {
  72. var credits = [].map.call(doc.querySelectorAll('#filmography .head'), function(e) {
  73. return +(e.textContent.match(/\((\d+) credits?\)/i) || [])[1];
  74. });
  75. if (!credits.length)
  76. return;
  77. var creditsSum = credits.reduce(function(sum, e) { return sum + e; }, 0);
  78. var worksNum = credits[0] + (credits.length > 1 ? '/' + creditsSum : '');
  79. showWorksNum(options.link, worksNum);
  80. localStorage[options.cacheKey] = '' + (Date.now() + CACHE_DURATION) + '\t' + worksNum;
  81. }
  82.  
  83. function doXHR(options) {
  84. if (document.readyState == 'complete') {
  85. sendRequest(options);
  86. return;
  87. }
  88. if (!doXHR.queue)
  89. initQueue();
  90. if (!isDupe()) {
  91. doXHR.queue.push(options);
  92. doXHR.queuedUrl[options.url] = options;
  93. }
  94.  
  95. function sendRequest(options) {
  96. var xhr = new XMLHttpRequest();
  97. xhr.open('GET', options.url);
  98. xhr.responseType = 'document';
  99. xhr.onload = function(e) {
  100. options.onload(xhr.response, options);
  101. doXHR.activeRequests--;
  102. poolQueue();
  103. };
  104. doXHR.activeRequests++;
  105. xhr.send();
  106. }
  107.  
  108. function initQueue() {
  109. doXHR.queue = [];
  110. doXHR.queuedUrl = {};
  111. doXHR.activeRequests = 0;
  112. document.addEventListener('DOMContentLoaded', function docLoaded() {
  113. document.removeEventListener('DOMContentLoaded', docLoaded);
  114. poolQueue();
  115. });
  116. }
  117.  
  118. function isDupe() {
  119. var dupe = doXHR.queuedUrl[options.url];
  120. if (!dupe)
  121. return false;
  122. if (dupe.link == options.link)
  123. return true;
  124. // this request's link element will use the will-be-cached data from the earlier queued request
  125. options.url = '';
  126. var _onload = dupe.onload;
  127. dupe.onload = function() {
  128. _onload.apply(null, arguments);
  129. showWorksNum(options.link, localStorage[options.cacheKey].split('\t')[1]);
  130. };
  131. return true;
  132. }
  133.  
  134. function poolQueue() {
  135. while (doXHR.queue.length && doXHR.activeRequests < 16) {
  136. sendRequest(doXHR.queue.shift());
  137. }
  138. }
  139. }

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址