NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
/* The MIT License (MIT) Copyright (c) <year> <copyright holders> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ // ==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 // @include http://www.pixiv.net/member_illust.php?mode=manga&illust_id=* // @version 2.0 // ==/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. // This script is kept up-to-date on the Greasy Fork network: // https://greasyfork.org/en/scripts/4714-eza-s-pixiv-fixiv // 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. // 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." // Simplified resizing with CSS. 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. 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 class='display' 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></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