您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adding album links and headers to tracks on Last.Fm's recent plays listings
当前为
// ==UserScript== // @name Stig's Last.fm Album Linkr // @namespace dk.rockland.userscript.lastfm.linkr // @description Adding album links and headers to tracks on Last.Fm's recent plays listings // @version 2016.07.07.0 // @author Stig Nygaard, http://www.rockland.dk // @homepageURL http://www.rockland.dk/userscript/lastfm/linkr/ // @supportURL http://www.rockland.dk/userscript/lastfm/linkr/ // @match *://*.last.fm/* // @match *://*.lastfm.de/* // @match *://*.lastfm.es/* // @match *://*.lastfm.fr/* // @match *://*.lastfm.it/* // @match *://*.lastfm.ja/* // @match *://*.lastfm.pl/* // @match *://*.lastfm.pt/* // @match *://*.lastfm.ru/* // @match *://*.lastfm.sv/* // @match *://*.lastfm.tr/* // @match *://*.lastfm.zh/* // @grant none // @noframes // ==/UserScript== var linkr = linkr || { // CHANGELOG - The most important updates/versions: changelog: [ {version: '2016.07.07.0', description: 'Album "headers" in play listings added.'}, {version: '2016.07.04.0', description: '1st release'} ], INFO: true, DEBUG: false, observed: null, linking_running: false, log: function(s, info) { if ((info && window.console) || (linkr.DEBUG && window.console)) { window.console.log('*Linkr* '+s); } }, insertStyle: function() { if (!document.getElementById('linkrStyle')) { var style = document.createElement('style'); style.type = 'text/css'; style.id = 'linkrStyle'; style.innerHTML = 'tr.albumlink-row, tr.albumlink-row > td {background-color:#888 !important;} ' + 'tr.albumlink-row > td a.link-block-target {color:#FFF !important;} '; document.getElementsByTagName('head')[0].appendChild(style); linkr.log('linkrStyle has been ADDED'); } else { linkr.log('linkrStyle was already present'); } }, linking: function (mutations) { if(linkr.linking_running) return; linkr.linking_running = true; function altvalue(elem) { if (elem && elem.firstElementChild) { if (elem.firstElementChild.classList.contains('albumlink-row')) { return null; } else if (elem.firstElementChild.firstElementChild && elem.firstElementChild.firstElementChild.firstElementChild && elem.firstElementChild.firstElementChild.firstElementChild.firstElementChild) { return elem.firstElementChild.firstElementChild.firstElementChild.firstElementChild.alt; } } return null; } linkr.log('Running linking()... ', linkr.INFO); var l = document.querySelectorAll('table.chartlist tr div > img'); for (var i=0; i < l.length; i++) { linkr.log('iteration '+ i + ' of ' + l.length); if (l[i].alt && l[i].alt!='') { //linkr.log('a - Found img.alt='+l[i].alt); l[i].title = l[i].alt; //linkr.log('b - img.title='+l[i].title); var tr = parent = l[i].parentNode; //linkr.log('c - tr.tagName='+tr.tagName); while (tr.tagName.toUpperCase()!=='TR') tr = tr.parentNode; //linkr.log('d - tr.tagName='+tr.tagName); var a = tr.querySelector('span.chartlist-artists a'); if (a) { linkr.log('e - Found img.alt='+l[i].alt); var albumlink = a.href + '/' + encodeURIComponent(l[i].alt).replace(/%20/g,'+') + '/'; linkr.log('giving albumlink='+albumlink); var link = document.createElement('a'); link.setAttribute('href', albumlink); parent.replaceChild(link, l[i]); link.appendChild(l[i]); } else { linkr.log('e - Artist link not found'); } } } var tlists = document.querySelectorAll('section#recent-tracks-section table.chartlist tbody, section.tracklist-section tbody'); linkr.log('tlists.length='+tlists.length); for (var j=0; j<tlists.length; j++) { linkr.log('Loop with tlists['+j+'].'); if (tlists[j] && tlists[j].children && tlists[j].children.length > 1) { linkr.log('tlists['+j+'] has ' + tlists[j].children.length + ' children'); for (i = 1; i < tlists[j].children.length; i++) { linkr.log('for-loop. i=' + i); if (i===1 || !tlists[j].children[i - 2].classList.contains('albumlink-row')) { linkr.log('for-loop. i=' + i + ' og i-2 er IKKE allerede albumlink-row'); if ( altvalue(tlists[j].children[i]) && altvalue(tlists[j].children[i - 1]) && altvalue(tlists[j].children[i]) != '' && altvalue(tlists[j].children[i]) === altvalue(tlists[j].children[i - 1]) && (i===1 || altvalue(tlists[j].children[i]) != altvalue(tlists[j].children[i - 2]))) { linkr.log('for-loop. i=' + i + ' og vi har fundet en album-gruppes start', linkr.INFO); // artistname defined below var artistlink = tlists[j].children[i].querySelector('td.chartlist-name span.chartlist-artists > a'); var albumtitle = altvalue(tlists[j].children[i]); var albumcover = tlists[j].children[i].querySelector('td.chartlist-play a > img'); if (albumcover) albumcover=albumcover.src; // albumlink defined below if (artistlink) { var artistname = artistlink.textContent; artistlink = artistlink.href; albumlink = artistlink + '/' + encodeURIComponent(altvalue(tlists[j].children[i])).replace(/%20/g,'+') + '/'; tr = document.createElement("tr"); tr.classList.add('albumlink-row'); tr.style.backgroundColor = '#888'; tr.style.color = '#FFF'; tr.innerHTML = '<td class="chartlist-play"><div class="chartlist-play-image"><a href="'+albumlink+'"><img title="'+albumtitle+'" src="'+albumcover+'" class="cover-art"></a></div></td><td class="chartlist-loved"><a href="'+albumlink.replace(/\/user\/[^\/]+\/library\//,'/')+'"><img src="http://www.rockland.dk/img/album244c.png" class="cover-art" alt="album" /></a></td><td class="chartlist-name"><span class="chartlist-ellipsis-wrap"><span class="chartlist-artists"><a href="'+artistlink+'" title="'+artistname+'">'+artistname+'</a></span><span class="artist-name-spacer"> — </span><a href="'+albumlink+'" class="link-block-target" title="'+artistname+' — '+albumtitle+'">'+albumtitle+'</a></span></td><td class="chartlist-buylinks"><div class="lazy-buylinks"><button class="disclose-trigger lazy-buylinks-toggle" aria-expanded="false" data-lazy-buylink="" data-lazy-buylink-url="'+albumlink.replace(/\/user\/[^\/]+\/library\//,'/')+'/+partial/buylinks">Buy</button></div></td><td class="chartlist-timestamp"></td><td class="chartlist-delete"></td>'; linkr.log('Now trying to add tr...'); tlists[j].insertBefore(tr, tlists[j].children[i - 1]); linkr.log('and should be added now!?'); i += 2; // or http://stackoverflow.com/questions/8766910/is-there-a-loop-start-over ? } } } } } else { linkr.log('but not enough children found???'); } } linkr.linking_running = false; }, setupObserver: function () { linkr.log('Running setupObserver()'); linkr.insertStyle(); linkr.observed = document.querySelector('table.chartlist > tbody'); if (!linkr.observed || !linkr.observed.classList) { linkr.log('Object to observe NOT found - re-trying later...'); } else if (linkr.observed.classList.contains('hasObserver')) { linkr.log('Everything is okay! - But checking again later...'); } else { linkr.linking(); linkr.log('Now adding Observer and starting...', linkr.INFO); var observer = new MutationObserver(linkr.linking); var config = {attributes: false, childList: true, subtree: false, characterData: false}; observer.observe(linkr.observed, config); linkr.observed.classList.add('hasObserver'); linkr.log('Observer added and running...'); } }, init: function () { linkr.log('Running init() on last.fm'); linkr.insertStyle(); linkr.linking(); setInterval(linkr.setupObserver,2000); } }; linkr.init();