// ==UserScript==// // @name IMDB works# // @description Shows number of credited works after names on IMDB site // @match *://*.imdb.com/* // @version 1.0.2 // @author wOxxOm // @namespace wOxxOm.scripts // @license MIT License // @grant GM_addStyle // @grant GM_xmlhttpRequest // @run-at document-start // @require https://greasyfork.org/scripts/12228/code/setMutationHandler.js // @downloadURL none // ==/UserScript== var SELECTOR = 'a[href^="/name/nm"]'; var CACHE_DURATION = 30 * 24 * 3600 * 1000; // 1 month GM_addStyle( '.number-of-works { opacity: 0.5; transition: opacity .25s ease-in-out .25s; }' + '.number-of-works:hover { opacity: 1.0; }' + '.number-of-works:before { content: " ["; opacity: 0.5; }' + '.number-of-works:after { content: "]"; opacity: 0.5; }' ); process(document.querySelectorAll(SELECTOR)); setMutationHandler(document, SELECTOR, process); function process(links) { var now = Date.now(); for (var link, i = 0; (link = links[i++]); ) { if (link.querySelector('img') || !link.textContent.trim() || link.nextElementSibling && link.nextElementSibling.matches('.number-of-works')) continue; var id = (link.href.match(/\/name\/nm(\d+)\/?(?:\?.*)?$/) || [])[1]; if (!id) continue; var cacheKey = 'works#' + id; var cache = (localStorage[cacheKey] || '').split('\t'); if (cache.length == 2 && +cache[0] && cache[1]) { showWorksNum(link, cache[1]); var isFresh = +cache[0] > now; if (isFresh) continue; } doXHR({ url: link.pathname, link: link, cacheKey: cacheKey, onload: parseNamePage, }); } } function showWorksNum(link, num, needsUpdate) { if (link.nextElementSibling && link.nextElementSibling.matches('.number-of-works')) { link.nextElementSibling.textContent = num; delete link.nextElementSibling.dataset.updating; } else { link.insertAdjacentHTML('afterend', '' + num + ''); } } function parseNamePage(doc, options) { var credits = [].map.call(doc.querySelectorAll('#filmography .head'), function(e) { return +(e.textContent.match(/\((\d+) credits?\)/i) || [])[1]; }); if (!credits.length) return; var creditsSum = credits.reduce(function(sum, e) { return sum + e; }, 0); var worksNum = credits[0] + (credits.length > 1 ? '/' + creditsSum : ''); showWorksNum(options.link, worksNum); localStorage[options.cacheKey] = '' + (Date.now() + CACHE_DURATION) + '\t' + worksNum; } function doXHR(options) { if (document.readyState == 'complete') { sendRequest(options); return; } if (!doXHR.queue) { doXHR.queue = []; window.addEventListener('load', function docLoaded() { window.removeEventListener('load', docLoaded); while (doXHR.queue.length) { sendRequest(doXHR.queue.shift()); } }); } if (!doXHR.queue.some(function(e) { return e.url == options.url; })) { doXHR.queue.push(options); } function sendRequest(options) { var xhr = new XMLHttpRequest(); xhr.open('GET', options.url); xhr.responseType = 'document'; xhr.onload = function(e) { options.onload(xhr.response, options); }; xhr.send(); } }