Eza's Pixiv Fixiv

Loads all manga pages at once in a simplified vertical layout

目前為 2017-04-18 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==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=*
// @include     https://www.pixiv.net/member_illust.php?mode=manga&illust_id=*
// @version     2.3
// ==/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 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. 
// 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. 
// Finally wrapped my head around CSS classes being hierarchical in <style>, i.e. <div class=foo><img class=bar></div> goes ".foo img .bar{}" - but can't figure out "force fit."
	// Oh, it's '100%'. Because viewheight and pixel figures don't respect aspect ratio... but percent does. CSS makes JS look consistent and obvious. 
	// Nope, it just defaults to fit-width. Grrr. 
	// Can I give it a ridiculous display size such that max-height and max-width take care of it? No. 
	// Can I set width=100% and max-height=100%? No. It just fits width and overflows height. max-height=100vh? No. It stretches. 
	// Ah, can't height=100% because it's the height of the div container, not the screen. Still, can I set height=100vh and max-width=100%? No, because it stretches. Arg! 
	// Does "calc" cover something like "100% or auto, whichever is smaller?" No.
	// Can max-height be set to "auto?" No. 
	// Jesus! There IS a just-fucking-fit-it solution - it's called object-fit. Except, because CSS is the devil, it puts tons of whitespace between images. FML.
		// That's an acceptable bug - and it is a bug, because it's not what I'm trying to do - since that spacing is how Pixiv works by default. Ugh, but the image links are floating...
		// More weirdness: it seems to scale the display of the image, but not the image container. My image-toolbar hovers off the visible image. 
		// Aha! width: 100vw; object-fit: contain; max-height: 100vh; basically gets it. Whitespace on sides of image is still treated as part of the image. 
		// Whitespace bug needs to be worked around because it's inconsistent with other scaling modes' behavior. Whitespace isn't generally clickable. 
	// Bless you, Shih-Min Lee on http://stackoverflow.com/questions/3029422/image-auto-resize-to-fit-div-container - nobody else understands "best fit." 

// https://i.pximg.net/img-master/img/2017/03/08/06/42/48/61802872_p0_master1200.jpg - problems in pixiv.context.images
// https://i.pximg.net/img-original/img/2017/03/08/06/42/48/61802872_p0.png - failed
// https://i.pximg.net/img-original/img/2017/03/08/06/42/48/61802872_p0.png - worked
// Might've just been load issues 
// Maybe display the default size (straight from pixiv.context.images) and link the huge version? Fuck, but then there's no way to test original file extension. 

// Maybe display default size, but have a button to switch to / load the big ones? Same on_error code. Still beats base Pixiv. 
	// Cons: breaks existing functionality (automatic highest resolution). 

// Accounted for pximg CDN, fixing a softlock.
// Changed onerror function to drive thumbnails from main images. 
// Added HTTPS. 



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 = "<div id='gallery_div' class='fit_if_larger'><center>"; 		// Bare high-res images, absent any delayed loading, with links below each one
var style_html = "<style> "; 		// Style block for controlling image scale via the div's class names 

	// 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. 

	if( pixiv.context.images[0].indexOf( 'pximg' ) < 0 ) { 		// Pixiv now sometimes uses a CDN with slightly different URL structure. At random. Wheee. 
		page_url = page_url.replace( 'c/1200x1200/img-master', 'img-original' ); 		// Change 1200-sized URL into original-sized URL
	} else { 		// This is the barely-different fix for the new CDN URLs
		page_url = page_url.replace( 'img-master', 'img-original' ); 
	}
	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.
		// Each image's onError additionally changes the associated thumbnail and link.
	var image_onerror = 'this.src=this.src.replace(".png",".gif"); this.src=this.src.replace(".jpg",".png");'
	image_onerror += 'getElementById("' + page_number + 'link").href=this.src;'
	image_onerror += 'getElementById("' + page_number + 'thumb").src=this.src;'

		// 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 alt='X' class='display' id='" + page_number + "thumb' src='" + page_url + "' height='100' width='auto'></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
	images_html += "<img alt='X' class='display' src='" + page_url + "' onerror='" + image_onerror + "'></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></div></center>";		// One last anchor, so clicking the last image goes to the end of the page 

	// Create controls for image size, since full-size images can be extremely large.
options_html += "<button class='auto' onclick=\"document.getElementById('gallery_div').className='fit_if_larger'\">Fit if larger</button> ";
options_html += "<button class='auto' onclick=\"document.getElementById('gallery_div').className='force_fit'\">Force fit</button> ";
options_html += "<button class='auto' onclick=\"document.getElementById('gallery_div').className='fit_height'\">Fit height</button> ";
options_html += "<button class='auto' onclick=\"document.getElementById('gallery_div').className='fit_width'\">Fit width</button> ";
options_html += "<button class='auto' onclick=\"document.getElementById('gallery_div').className=''\">Original sizes</button> ";

	// Define CSS to scale images in various ways.
style_html += "<style> "; 		// I accidentally open <style> twice in the style_html string... but the script fails without both. What the fuck. 
style_html += "img{ height:auto; width:auto; } "; 
style_html += "img.thumbnail { height: 100px; width: auto; } "; 
style_html += ".fit_if_larger img.display { max-height: 100vh; max-width: 100vw; } "; 
style_html += ".force_fit img.display { width: 100vw; object-fit: contain; max-height: 100vh; } ";
style_html += ".fit_height img.display { height: 100vh; } "; 
style_html += ".fit_width img.display { width: 100vw; } "; 
style_html += "</style>"; 

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