您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds additional information (genre, rating, keywords)to igdb.com lists. They can be loaded witha button // click. Needs an IGDB api key.
当前为
// ==UserScript== // @name IGDB List Extra Info // @namespace https://greasyfork.org/de/users/155913-nkay08 // @description Adds additional information (genre, rating, keywords)to igdb.com lists. They can be loaded witha button // click. Needs an IGDB api key. // // @author NKay // @include http*://www.igdb.com/* // @grant none // @require http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js // @version 0.0.1.20171119132304 // ==/UserScript== //insert your API-KEY here var apikey = ''; var apiurl; var req; var reqid; var corsproxy; var fields; var myheaders; var gametextarray; var gameidarray; var genresnodearray; var keywordsnodearray; var ratingnodearray; var idortext; var keyelement = "div.content-left.col-md-pull-10.col-md-2"; //only execute function if this element is loaded via ajax waitForKeyElements(keyelement, checkForElement); //waitForKeyElements(keyelement,alert1); function alert1(){ alert('alert'); } function init() { apiurl = 'https://api-2445582011268.apicast.io'; req = '/games/?search='; reqid = '/games/1942?fields=*'; corsproxy = 'https://cors-anywhere.herokuapp.com/'; fields = '?fields=genres,keywords,rating,rating_count,aggregated_rating,aggregated_rating_count,total_rating,total_rating_count'; myheaders = new Headers(); myheaders.append('user-key', apikey); //myheaders.append('Accept', 'application/json'); gametextarray = []; gameidarray = []; genresnodearray = []; keywordsnodearray = []; ratingnodearray = []; idortext = 'text'; } function checkForElement(jnode) { if (!document.getElementById('btnaddinfo')) { init(); addButton(); addAdditionalInfo(); } } function populateGametextarray(element) { //get the game name var span1 = element.getElementsByTagName('span'); var gametext = span1[0].innerHTML; var cururl = corsproxy + apiurl + req + gametext; gametextarray.push(cururl); } function populateGameidarray(element) { // get sibling. sibling has game id var sib = element.nextSibling; var gameid = sib.getAttribute("data-game"); } function addTextNodes(div) { for (var i = 0; i < div.length; i++) { // console.log(div[i]); addTextNode(div[i], i); } } function addTextNode(el, i) { var genrestext = document.createTextNode('Genres: '); var genresspan = document.createElement('span'); genresspan.style.fontSize = 'medium'; genresspan.style.textDecoration = 'underline'; genresspan.appendChild(genrestext); el.appendChild(genresspan); var genresnode = document.createElement('span'); genresnode.setAttribute("id", "usgenre" + i.toString()); el.appendChild(genresnode); genresnodearray.push(genresnode); el.appendChild(document.createTextNode(' | ')); var keywordstext = document.createTextNode('Keywords: '); var kwspan = document.createElement('span'); kwspan.style.fontSize = 'medium'; kwspan.style.textDecoration = "underline"; kwspan.appendChild(keywordstext); el.appendChild(kwspan); var keywordsnode = document.createElement('span'); keywordsnode.setAttribute("id", "uskw" + i.toString()); el.appendChild(keywordsnode); keywordsnodearray.push(keywordsnode); el.appendChild(document.createTextNode(' | ')); var ratingtext = document.createTextNode('Rating: '); var rtspan = document.createElement('span'); rtspan.style.fontSize = 'medium'; rtspan.style.textDecoration = "underline"; rtspan.appendChild(ratingtext); el.appendChild(rtspan); var ratingnode = document.createTextNode(''); el.appendChild(ratingnode); ratingnodearray.push(ratingnode); if (idortext == 'text') { populateGametextarray(el); } if (idortext == 'id') { populateGameidarray(el); } } function addButton() { //add Button var btn = document.createElement("button"); var btntext = document.createTextNode('Load additional info'); btn.appendChild(btntext); btn.addEventListener("click", function() { load(idortext); }, false); btn.setAttribute("id", "btnaddinfo"); var sidebar = document.getElementsByClassName("user-details-sidebar"); if (sidebar) { var sibling = sidebar[0].nextSibling; sibling.parentNode.insertBefore(btn, sibling); sibling.parentNode.insertBefore(document.createElement("hr"), sibling); } function load(str) { if (str == "text") { loadbytext(); } if (str == "id") { loadbyid(); } } // var firstbtn = document.getElementsByClassName("panel-title"); // firstbtn[0].parentNode.insertBefore(document.createElement('hr'), firstbtn[0]); // firstbtn[0].parentNode.insertBefore(btn, firstbtn[0]); // firstbtn[0].parentNode.insertBefore(document.createElement('hr'), firstbtn[0]); } function addAdditionalInfo(jnode) { console.log('Adding button and placeholders for extra info'); // var pageDivs = document.getElementsByClassName("media-body"); // addTextNodes(pageDivs); var selector = "#content-page > div > div.content-left.col-md-push-2.col-md-10 > div:nth-child(2) > div.panel-body.listentries > div > div:nth-child(n) > div.media-body"; var selector2 = "#content-page > div > div.content-left.col-md-push-2.col-md-10 > div > div.panel-body.listentries > div > div:nth-child(5) > div"; var selectorgen ="div > div.panel-body.listentries > div > div:nth-child(n) > div"; var queryres = document.querySelectorAll(selectorgen); addTextNodes(queryres); // console.log(queryres); } function loadbytext() { genresnodearray.forEach(element => element.innerHTML = 'loading..'); keywordsnodearray.forEach(element => element.innerHTML = 'loading..'); ratingnodearray.forEach(element => element.nodeValue = 'loading..'); //execute multiple fetch promises //first fetch the game-id for a given name Promise.all( gametextarray.map( (url, index) => fetch(url, { headers: myheaders }) .then(res => res.json()) .then(data => { var gameidnum = data[0].id; var gameid = gameidnum.toString(); //generate new url with id to query for the data var newurl = (corsproxy + apiurl + '/games/' + gameid + fields); return fetch(newurl, { headers: myheaders }); }) .then(res2 => res2.json()) .then(data2 => { if (data2) { var ratingstr = ''; ratingstr = ratingstr.concat('User: '); if (data2[0].rating) { ratingstr = ratingstr.concat(Math.round(data2[0].rating).toString()); ratingstr = ratingstr.concat(' (' + data2[0].rating_count.toString() + ')'); } else { ratingstr = ratingstr.concat('/'); } ratingstr = ratingstr.concat(', '); ratingstr = ratingstr.concat('Critics: '); if (data2[0].aggregated_rating) { ratingstr = ratingstr.concat(Math.round(data2[0].aggregated_rating).toString()); ratingstr = ratingstr.concat(' (' + data2[0].aggregated_rating_count.toString() + ')'); } else { ratingstr = ratingstr.concat('/'); } ratingstr = ratingstr.concat(', '); ratingstr = ratingstr.concat('Total: '); if (data2[0].total_rating) { ratingstr = ratingstr.concat(Math.round(data2[0].total_rating).toString()); ratingstr = ratingstr.concat(' (' + data2[0].total_rating_count.toString() + ')'); } else { ratingstr = ratingstr.concat('/'); } ratingnodearray[index].nodeValue = ratingstr; //concat all genrenames. fetch for all genre-ids at once if (data2[0].genres) { var genresid = data2[0].genres; var genresurl = corsproxy + apiurl + '/genres/' + data2[0].genres.toString(); fetch(genresurl, { headers: myheaders }) .then(resgenre => resgenre.json()) .then(datagenre => { var newgenres = ''; genresnodearray[index].innerHTML = ''; datagenre.forEach((tgenre, genreindex) => { var newgenre = document.createElement('a'); newgenre.setAttribute("href", tgenre.url); var comma = ', '; if (genreindex == datagenre.length - 1) { comma = ''; } newgenre.appendChild(document.createTextNode(tgenre.name + comma)); genresnodearray[index].appendChild(newgenre); }); }); } //concat all keywords. fetch for all keyword-ids at once if (data2[0].keywords) { var keywordsid = data2[0].keywords; var keywordsurl = corsproxy + apiurl + '/keywords/' + data2[0].keywords.toString(); fetch(keywordsurl, { headers: myheaders }) .then(reskey => reskey.json()) .then(datakey => { keywordsnodearray[index].innerHTML = ''; datakey.forEach((tkey, keyindex) => { var newkey = document.createElement('a'); newkey.setAttribute('href', tkey.url); var comma = ', '; if (keyindex == datakey.length - 1) { comma = ''; } newkey.appendChild(document.createTextNode(tkey.name + comma)); keywordsnodearray[index].appendChild(newkey); }); }); } } }) ) ); } function loadbyid() { genresnodearray.forEach(element => element.innerHTML = 'loading..'); keywordsnodearray.forEach(element => element.innerHTML = 'loading..'); ratingnodearray.forEach(element => element.nodeValue = 'loading..'); Promise.all( gameidarray.map( (url, index) => fetch(url, { headers: myheaders }) .then(res2 => res2.json()) .then(data2 => { if (data2) { var ratingstr = ''; ratingstr = ratingstr.concat('User: '); if (data2[0].rating) { ratingstr = ratingstr.concat(Math.round(data2[0].rating).toString()); ratingstr = ratingstr.concat(' (' + data2[0].rating_count.toString() + ')'); } else { ratingstr = ratingstr.concat('/'); } ratingstr = ratingstr.concat(', '); ratingstr = ratingstr.concat('Critics: '); if (data2[0].aggregated_rating) { ratingstr = ratingstr.concat(Math.round(data2[0].aggregated_rating).toString()); ratingstr = ratingstr.concat(' (' + data2[0].aggregated_rating_count.toString() + ')'); } else { ratingstr = ratingstr.concat('/'); } ratingstr = ratingstr.concat(', '); ratingstr = ratingstr.concat('Total: '); if (data2[0].total_rating) { ratingstr = ratingstr.concat(Math.round(data2[0].total_rating).toString()); ratingstr = ratingstr.concat(' (' + data2[0].total_rating_count.toString() + ')'); } else { ratingstr = ratingstr.concat('/'); } ratingnodearray[index].nodeValue = ratingstr; //concat all genrenames. fetch for all genre-ids at once if (data2[0].genres) { var genresid = data2[0].genres; var genresurl = corsproxy + apiurl + '/genres/' + data2[0].genres.toString(); fetch(genresurl, { headers: myheaders }) .then(resgenre => resgenre.json()) .then(datagenre => { var newgenres = ''; genresnodearray[index].innerHTML = ''; datagenre.forEach((tgenre, genreindex) => { var newgenre = document.createElement('a'); newgenre.setAttribute("href", tgenre.url); var comma = ', '; if (genreindex == datagenre.length - 1) { comma = ''; } newgenre.appendChild(document.createTextNode(tgenre.name + comma)); genresnodearray[index].appendChild(newgenre); }); }); } //concat all keywords. fetch for all keyword-ids at once if (data2[0].keywords) { var keywordsid = data2[0].keywords; var keywordsurl = corsproxy + apiurl + '/keywords/' + data2[0].keywords.toString(); fetch(keywordsurl, { headers: myheaders }) .then(reskey => reskey.json()) .then(datakey => { keywordsnodearray[index].innerHTML = ''; datakey.forEach((tkey, keyindex) => { var newkey = document.createElement('a'); newkey.setAttribute('href', tkey.url); var comma = ', '; if (keyindex == datakey.length - 1) { comma = ''; } newkey.appendChild(document.createTextNode(tkey.name + comma)); keywordsnodearray[index].appendChild(newkey); }); }); } } }) ) ); } /*--- waitForKeyElements(): A utility function, for Greasemonkey scripts, that detects and handles AJAXed content. Usage example: waitForKeyElements ( "div.comments" , commentCallbackFunction ); //--- Page-specific function to do what we want when the node is found. function commentCallbackFunction (jNode) { jNode.text ("This comment changed by waitForKeyElements()."); } IMPORTANT: This function requires your script to have loaded jQuery. */ function waitForKeyElements( selectorTxt, /* Required: The jQuery selector string that specifies the desired element(s). */ actionFunction, /* Required: The code to run when elements are found. It is passed a jNode to the matched element. */ bWaitOnce, /* Optional: If false, will continue to scan for new elements even after the first match is found. */ iframeSelector /* Optional: If set, identifies the iframe to search. */ ) { var targetNodes, btargetsFound; if (typeof iframeSelector == "undefined") targetNodes = $(selectorTxt); else targetNodes = $(iframeSelector).contents() .find(selectorTxt); if (targetNodes && targetNodes.length > 0) { btargetsFound = true; /*--- Found target node(s). Go through each and act if they are new. */ targetNodes.each(function() { var jThis = $(this); var alreadyFound = jThis.data('alreadyFound') || false; if (!alreadyFound) { //--- Call the payload function. var cancelFound = actionFunction(jThis); if (cancelFound) btargetsFound = false; else jThis.data('alreadyFound', true); } }); } else { btargetsFound = false; } //--- Get the timer-control variable for this selector. var controlObj = waitForKeyElements.controlObj || {}; var controlKey = selectorTxt.replace(/[^\w]/g, "_"); var timeControl = controlObj[controlKey]; //--- Now set or clear the timer as appropriate. if (btargetsFound && bWaitOnce && timeControl) { //--- The only condition where we need to clear the timer. clearInterval(timeControl); delete controlObj[controlKey]; } else { //--- Set a timer, if needed. if (!timeControl) { timeControl = setInterval(function() { waitForKeyElements(selectorTxt, actionFunction, bWaitOnce, iframeSelector ); }, 300 ); controlObj[controlKey] = timeControl; } } waitForKeyElements.controlObj = controlObj; }