您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Turns thumbnail titles into direct or mode=manga links, adds direct image links on mode=manga pages, replaces the medium thumbnail on mode=medium pages with the full size, and disables lazy-loading images.
当前为
// ==UserScript== // @name Pixiv Direct Links // @namespace https://greasyfork.org/scripts/4555 // @description Turns thumbnail titles into direct or mode=manga links, adds direct image links on mode=manga pages, replaces the medium thumbnail on mode=medium pages with the full size, and disables lazy-loading images. // @include http://www.pixiv.net* // @grant GM_xmlhttpRequest // @version 2014.09.28 // ==/UserScript== //Turn thumbnail titles into direct links (single images) or mode=manga links. GM_xmlhttpRequest is required for images uploaded after ~2014/09/24. Title links are disabled by default when GM_xmlhttpRequest() isn't available but can be enabled anyway by changing this setting to just "true". var directTitles = ( typeof(GM_xmlhttpRequest) != "undefined" ); //Append direct links below images on mode=manga pages var directManga = true; //Replace the medium thumbnail on mode=medium pages with (and link it to) the full size. If GM_xmlhttpRequest is available, the old-style URL is used. var fullSizeMedium = true; //Disable lazy loading images. These appear on mode=manga pages, rankings, and the "Recommended" section of the bookmarks page. var dontSayLazy = true; //----------------------------------------------------------------// if( location.search.indexOf("mode=manga_big") > 0 || location.search.indexOf("mode=big") > 0 ) { //Make the 'big'/'manga_big' image link to itself instead of closing the window var image = document.getElementsByTagName("img")[0]; if( image ) { var link = document.createElement("a"); link.href = image.src; link.appendChild( document.createElement("img") ).src = image.src; document.body.innerHTML = ""; document.body.appendChild( link ); } } else if( location.search.indexOf("mode=manga") > 0 ) { var container = document.getElementsByClassName("full-size-container"); if( directManga && container.length ) { //Check the mode=manga_big page for the first page to determine if the "_big_p" size exists. var req = new XMLHttpRequest(); req.open( "GET", location.href.replace('mode=manga','mode=manga_big&page=0'), true ); req.onload = function() { var firstImage = req.responseXML.querySelector("img[src*='_p0.']").src; for( var i = 0; i < container.length; i++ ) { //Add direct link below each page var link = document.createElement("a"); link.textContent = "direct link"; link.style.display = "block"; link.href = firstImage.replace( "_p0.", "_p"+i+"." ); container[i].parentNode.appendChild( link ); } } req.responseType = "document"; req.send(null); } } else if( window == window.top )//not inside iframe { if( directTitles ) { //Link dem titles. linkThumbTitles([document]); new MutationObserver( function(mutationSet) { mutationSet.forEach( function(mutation){ linkThumbTitles( mutation.addedNodes ); } ); }).observe( document.body, { childList:true, subtree:true } ); } //Full size image on mode=medium page: var mediumLink = location.search.indexOf("mode=medium") > 0 && document.querySelector(".works_display a[href*='mode='][href*='illust_id=']"); if( mediumLink ) { //Make link open in same window mediumLink.removeAttribute('target'); //If not manga, replace the thumbnail with the full size and point the link directly to the image instead of the mode=big page var mainImage = fullSizeMedium && mediumLink.href.indexOf("mode=big") > 0 && mediumLink.getElementsByTagName("img")[0]; if( mainImage ) { mainImage.setAttribute("style", "max-width: 740px; height: auto; width: auto;"); if( mainImage.src.indexOf("_m.") > 0 ) mediumLink.href = mainImage.src = mainImage.src.replace("_m.","."); else if( typeof(GM_xmlhttpRequest) != "undefined" ) queryAPI( [{ "id": mediumLink.href.match(/illust_id=(\d+)/)[1], "link": mediumLink, "image": mainImage.src, "fullsize": mainImage }] ); else { //New thumbnails are always jpg, need to query mode=big page (only seems to work from mode=medium pages) to get the right file extension. var req = new XMLHttpRequest(); req.open( "GET", mediumLink.href, true ); req.onload = function(){ mediumLink.href = mainImage.src = req.responseXML.getElementsByTagName("img")[0].src; } req.responseType = "document"; req.send(null); } } } } if( dontSayLazy && unlazyImage() && window == window.top ) { //Initial page has lazy images; listen for more images added later new MutationObserver( function(mutationSet) { mutationSet.forEach( function(mutation) { for( var i = 0; i < mutation.addedNodes; i++ ) unlazyImage( mutation.addedNodes[i] ); } ); }).observe( document.body, { childList:true, subtree:true } ); } //----------------------------------------------------------------// function unlazyImage(target) { var images = ( target || document ).querySelectorAll("img[data-src]"); for( var i = 0; i < images.length; i++ ) images[i].src = images[i].getAttribute("data-src"); return images.length; } function linkThumbTitles(targets) { var titleList = []; for( var i = 0; i < targets.length; i++ ) { //Change titles on ranking pages: var rankTitle = targets[i].querySelectorAll(".ranking-item a.title[href*='mode=medium'][href*='illust_id=']"); for( var j = 0; j < rankTitle.length; j++ ) titleList.push({ "id": rankTitle[j].href.match(/illust_id=(\d+)/)[1], "link": rankTitle[j] }); //Most thumbnails: var image = targets[i].querySelectorAll("li a[href*='mode=medium'][href*='illust_id='] img"); for( var j = 0; j < image.length; j++ ) { var page, title; for( page = image[j].parentNode; page.tagName != "A"; page = page.parentNode ); //The prev/next thumbnails on mode=medium pages have text before/after the image. Text also follows the image on image responses listings. if( !(title = page.getElementsByClassName("title")[0]) && (title = page.lastChild).nodeName != '#text' && (title = page.firstChild).nodeName != '#text' ) continue;//Can't find title element if( image[j].parentNode.classList.contains("ugoku-illust") ) continue;//Ugoira animation //Start title link at mode=medium and change later. var titleLink = document.createElement("a"); titleLink.href = page.href; titleLink.style.color = "#333333";//Style used on some pages //Move the title out of the thumbnail link page.removeChild(title); titleLink.appendChild(title); page.parentNode.insertBefore( titleLink, page.nextSibling ); titleList.push({ "id": page.href.match(/illust_id=(\d+)/)[1], "link": titleLink, "image": image[j].src }); } } if( !titleList.length ) return; if( typeof(GM_xmlhttpRequest) != "undefined" ) queryAPI( titleList ); else for( var i = 0; i < titleList.length; i++ ) directLinkSingle( titleList[i] ); } function queryAPI(titleList) { var query = "http://spapi.pixiv.net/iphone/illust.php?illust_id="+titleList[0].id; for( var i = 1; i < titleList.length; i++ ) query += ","+titleList[i].id; //Session ID is needed for R-18 images var sessionID = document.cookie.match(/PHPSESSID=[^;]+/)[0]; if( sessionID ) query += "&"+sessionID; GM_xmlhttpRequest( { method: "GET", url: query, onload: function(responseDetails) { var result = [], quote = false; //Strip quotes and commas inside of quotes, for easier parsing later for( var i = 0; i < responseDetails.responseText.length; i++ ) { if( responseDetails.responseText[i] == '"' ) quote = !quote; else if( !quote || responseDetails.responseText[i] != ',' ) result.push( responseDetails.responseText[i] ); } result = result.join("").split("\n"); for( var i = 0; i < result.length && result[i].length; i++ ) { var matcher, parr = result[i].split(","); for( var j = 0; j < titleList.length; j++ ) if( parr[0] == titleList[j].id ) { //[ 0]: illust_id //[ 2]: extension //[ 9]: http://i2.pixiv.net/img04/img/aenobas/mobile/30095810_480mw.jpg?1348946035 (always jpg) //[19]: # pages (empty if not manga) if( /^\d+$/.test(parr[19]) ) { titleList[j].link.href = titleList[j].link.href.replace("mode=medium","mode=manga"); //Append the page count to the title attribute ( titleList[j].link.firstChild.nodeName == '#text' ? titleList[j].link : titleList[j].link.firstChild ).title += " ("+parr[19]+"p)"; } else if( (matcher = parr[9].match( /(.*\/img\d+\/img\/[^\/]+\/)mobile\/[^?]+(.*)/ )) != null ) { titleList[j].link.href = matcher[1]+parr[0]+"."+parr[2]+matcher[2];//baseURL + illustID + "." + extension + revision if( titleList[j].fullsize ) titleList[j].fullsize.src = titleList[j].link.href; } //Remove title from list titleList.splice( j, 1 ); break; } } //Individually query whatever didn't get matched above for( var i = 0; i < titleList.length; i++ ) directLinkSingle( titleList[i] ); } }); } //Fallback method to query each image's mode=medium page. Doesn't work on images after Sept 2014. function directLinkSingle(title) { if( title.image && title.image.indexOf("img-master") > 0 ) return;//New medium thumbnails can't be reliably converted to full size because they are always jpg var req = new XMLHttpRequest(); req.open( "GET", "http://www.pixiv.net/member_illust.php?mode=medium&illust_id="+title.id, true );//Not mode=big, since that only seems to work from mode=medium pages... req.onload = function() { var modeLink = req.responseXML.querySelector(".works_display a[href*='mode=']"); if( modeLink.href.indexOf("mode=manga") > 0 ) title.link.href = modeLink.href; else if( modeLink.href.indexOf("mode=big") > 0 ) title.link.href = modeLink.querySelector("img[src*='_m.']").src.replace("_m.","."); } req.responseType = "document"; req.send(null); }