Eza's Pixiv Fixiv

Loads all manga pages at once in a simplified vertical layout

目前为 2015-08-23 提交的版本。查看 最新版本

// ==UserScript==
// @name        Eza's Pixiv Fixiv
// @namespace   https://inkbunny.net/ezalias
// @description Loads all manga pages at once in a simplified vertical layout
// @license     MIT
// @license     Public domain / No rights reserved
// @include     http://www.pixiv.net/member_illust.php?mode=manga&illust_id=*
// @version     1.8
// ==/UserScript==



// On manga pages, load all images without having to manually scroll to each one. 
// Pixiv is terribly designed. Maybe it's a cultural Japanese thing, where they still expect single-page click-and-wait browsing like it's still 1998. The site is just openly hostile to users' time and enjoyment. 
// To wit, I recommend Eza's Image Glutton, which directs from the "medium" landing pages to either the full-size single image or the manga page. Tedium is for robots. 



// Should Pixiv Fixiv load real thumbnails? Pixiv provides them. It's not like Tumblr Scrape where you want to save the small images; they only exist to provide an overview. 
	// Using full-size images indicates when they're done loading. 
// Pixiv is now screwing with Image Toolbar. The toolbar appears with big icons and text labels (doubled text labels, in fact), and middle-clicking doesn't work. I hate this website. 
// Once the img-original thing works, add an option (using GM API) to switch between 1200-size and original-size images. 
	// Arg. @grant fucked me. '@grant none' says 'gm_getsetting not found.' '@grant gm_getsetting' says 'pixiv (the array) not found.' fuck your scope bullshit, greasemonkey. be unsafe and useful. 
// onError should only have to suss out image extensions once per image. Break it out into a function (onError="myFunction()") and have it change the big-image src's as well as the image-link href's. 
// Maybe add 'fit only if wider' and 'fit only if taller' buttons? mostly thinking 4koma / tall comics. 

// Added aspect-ratio-aware resizing. Added automatic resizing. Refactored buttons. Removed unused variables. 



var thumbnail_html = ""; 		// Clickable thumbnails that scroll down to each image
var options_html = "Scale images: "; 		// Fit-to-window buttons for oversized images  
var images_html = "<center>"; 		// Bare high-res images, absent any delayed loading, with links below each one

	// Build a simplified version of the manga page, using high-res images. Clicking an image jumps to the next one. (Keyboard controls not implemented.) 
for( var page_number = 0; page_number < pixiv.context.images.length; page_number++ ) { 
	var page_url = pixiv.context.images[ page_number ]; 		// Pixiv now helpfully provides a <script>-generated array of URLs. 
	page_url = page_url.replace( 'c/1200x1200/img-master', 'img-original' ); 		// Change 1200-sized URL into original-sized URL
	page_url = page_url.replace( '_master1200', '' ); 
	page_url = page_url.replace( '.png', '.jpg' ); 		// Change PNG to JPG - so we only have to do JPG->PNG in our onError function. 
	page_url = page_url.replace( '.gif', '.jpg' ); 			// Same deal, change GIF to JPG. onError cycles from JPG -> PNG -> GIF. 

		// onError function rotates incorrect file extensions, since the right one can't be sussed out beforehand.
	var image_onerror = 'this.src=this.src.replace(\".png\",\".gif\"); this.src=this.src.replace(\".jpg\",\".png\");'

		// Display thumbnails for an overview of this manga's contents (and easy links to each page) 
	thumbnail_html += "<a href='#" + page_number + "'>";		// link thumbnail to the relevant page anchor 
	thumbnail_html += "<img src='" + page_url + "' height='100' width='auto' onerror='" + image_onerror + "'></a> ";

		// Display pages centered, each linked to the next, kind of like Pixiv does
	images_html += "<a id='" + page_number + "'>"; 		// Anchor, to be linked to by top thumbnails and the previous page 
	images_html += "<a href='#" + (1.0+page_number) + "'>"; 		// Link this image to the next image's anchor
		// This onError additionally changes the associated text link to match the image:
	images_html += "<img class='display' src='" + page_url + "' onerror='" + image_onerror + " getElementById(\""+page_number+"link\").href=this.src;'></a></br>";  
	images_html += "<a id='" + page_number + "link' href='" + page_url + "'>Image link</a><br><br>"; 		// Link to the image, so it's easy to open a particular page in tabs
}
images_html += "<br><br><br><a id = '" + pixiv.context.images.length + "'></a></center>";		// Add one last anchor tag, so clicking the last image brings you to the end of the page 



	// Create controls for image size, since full-size images can be extremely large. (Single-instance pattern - only write repeated components once.)
var cancel_autofit = 'document.getElementById( "fit" ).className="no-auto";'; 
var foreach_image = 'var display_images = document.getElementsByClassName("display"); for(x=display_images.length-1;x>=0;x--)'; 
var if_wide_aspect_ratio = 'var image_ratio = display_images[x].naturalWidth / (display_images[x].naturalHeight+1);'; 		// +1 to divisor to avoid division-by-zero. Might be null anyway? Meh.  
	if_wide_aspect_ratio += 'var screen_ratio = window.innerWidth / window.innerHeight;';  
	if_wide_aspect_ratio += 'if( image_ratio > 0.9 * screen_ratio )'; 		// 0.9x multiplier to slightly favor fit-width over fit-height. Images that are too wide create an ugly horizontal scroll bar. 
var fit_width = 'display_images[x].style.width="100vw"; display_images[x].style.height="auto";'; 
var fit_height = 'display_images[x].style.width="auto"; display_images[x].style.height="100vh";'; 
var original_size = 'display_images[x].style.width="auto"; display_images[x].style.height="auto";'; 

	// Define buttons to affect all images onClick
var onclick_fit = cancel_autofit + foreach_image +' { if( display_images[x].naturalWidth < window.innerWidth && display_images[x].naturalHeight < window.innerHeight ) { ' + original_size + ' } ';
onclick_fit += 'else { ' + if_wide_aspect_ratio + ' { ' + fit_width + ' } else { ' + fit_height + ' } } }'; 
options_html += "<button id='fit' class='auto' onclick='" + onclick_fit + "'>Fit if larger</button> "; 		// Fit-to-window, leaving smaller images at native size

var onclick_force = cancel_autofit + foreach_image +' {' + if_wide_aspect_ratio + ' { ' + fit_width + ' } else { ' + fit_height + ' } }'; 
options_html += "<button onclick='" + onclick_force + "'>Force fit</button> "; 		// Fit-to-window for all images

var onclick_height = cancel_autofit + foreach_image +' { ' + fit_height + ' }';
options_html += "<button onclick='" + onclick_height + "'>Fit height</button> "; 		// Fit images to window height (wide images may scroll horizontally)

var onclick_width = cancel_autofit + foreach_image +' { ' + fit_width + ' }';
options_html += "<button onclick='" + onclick_width + "'>Fit width</button> "; 		// Fit images to window width (tall images may require scrolling down)

var onclick_original = cancel_autofit + foreach_image +' { ' + original_size + ' }';
options_html += "<button onclick='" + onclick_original + "'>Original sizes</button> "; 		// Native image size (which can be gigantic) 



	// Replace HTML body with our custom HTML. 
document.body.innerHTML = thumbnail_html + "<br>" + options_html + "<br><br>" + images_html; 		// Thumbnails, then options, then centered images 

	// Automatically click "Fit" button when page finishes loading, unless the user has manually clicked one of the Fit buttons 
window.onload = function () { if( document.getElementById( 'fit' ).className == 'auto' ) { document.getElementById( 'fit' ).click(); } };