// ==UserScript==
// @name Pixiv Display All Images
// @namespace superschwul
// @version 2.0
// @description Display all manga images automatically: no need to click the medium image.
// @homepageURL https://greasyfork.org/en/scripts/36886-pixiv-display-all-images
// @author Superschwul
// @match https://www.pixiv.net/stacc*
// @match https://www.pixiv.net/member*
// @match https://www.pixiv.net/bookmark*
// @grant window.close
// @run-at document-end
// @downloadURL none
// ==/UserScript==
// ===============================================================================
// USER OPTIONS
var FIT_IMAGES_TO_SCREEN_WIDTH_AND_HEIGHT = false;
var LOAD_HIGH_RESOLUTION_IMAGES = true;
// ===============================================================================
// CHANGELOG
// 2.0 2018-09-14 better ajax support
// 1.8 2018-09-13 added new member page support
// 1.7 2018-09-11 added ajax thumbs support
// 1.6 2018-09-02 fixed missing like button
// 1.5 2018-08-29 improved image src identification
// 1.4 2018-08-26 added hi-res option, improved avatar timing
// 1.3 2018-08-16 removed feedback button
// 1.2 2018-08-16 disabled sticky bar, added fit-to-screen option
// 1.1 2018-06-21 fixed image src url
// 1.0 2018-06-17 show original instead of master manga images
// 0.8 2018-06-15 added fixed avatar
// 0.7 2018-06-13 added link to works page at illustration page
// 0.6 2018-06-12 updated to work with the new pixiv layout
// 0.5 2018-01-07 hide buttons over thumbnails at works page
// 0.4 2018-01-04 enlarge thumbnails at works page
// 0.3 2018-01-03 replaced gm_xmlhttprequest by xmlhttprequest
// 0.2 2017-12-30 added support for rtl manga pages
// 0.1 2017-12-30 initial code
// ===============================================================================
function addLinkToMemberPageAtStaccPage() {
var intervalCount = 0;
var interval = setInterval(function() {
intervalCount++;
if(intervalCount >= 300) {
clearInterval(interval);
return;
}
var usernames = document.getElementsByClassName('stacc_ref_illust_user_name');
if(usernames != undefined) {
clearInterval(interval);
var i = 0;
for(i=0; i < usernames.length; i++) {
usernames[i].style.display = 'block';
var link = usernames[i].getElementsByTagName('a')[0].href;
link = link.replace('member', 'member_illust');
link = link.replace(/&from_sid=\d+/, '');
var a = document.createElement('a');
a.href = link;
a.target = '_blank';
a.style.display = 'block';
a.appendChild(document.createTextNode("More works"));
usernames[i].appendChild(a);
}
}
}, 200);
}
function displayGallery() {
//is it a single image, multiple vertical, or multiple rtl?
var intervalCount = 0;
var interval = setInterval(function() {
intervalCount++;
if(intervalCount >= 300) {
clearInterval(interval);
return;
}
var article = document.getElementsByTagName('article')[0];
var thumb;
if(article != undefined) {
thumb = article.getElementsByTagName('a')[0];
}
if(thumb != undefined) {
if(thumb.getElementsByTagName('img')[0] == undefined) {
clearInterval(interval);
return;
}
var imgSrc = thumb.getElementsByTagName('img')[0].src;
if(imgSrc != unsafeWindow.location.href) {
clearInterval(interval);
var thumbObserver = new MutationObserver(getGalleryImages);
thumbObserver.observe(thumb, {attributeFilter: ['href']});
addLinkToMemberPage();
getGalleryImages();
}
}
}, 200);
}
function removeGallery() {
if(document.getElementById('pil_gallery') != undefined) {
document.getElementById('pil_gallery').parentNode.removeChild(document.getElementById('pil_gallery'));
}
}
function getGalleryImages() {
removeGallery();
var thumb = document.getElementsByTagName('article')[0].getElementsByTagName('a')[0];
var type = 'single';
if(thumb.pathname == '/member_illust.php') {
type = 'vertical';
}
//get original images and fill gallery
if(type == 'single') {
getSingleOriginalImage(thumb);
} else {
getMultipleVerticalOriginalImages();
}
}
function addLinkToMemberPage() {
var intervalAvatarCount = 0;
var intervalAvatar = setInterval(function() {
intervalAvatarCount++;
if(intervalAvatarCount >= 300) {
clearInterval(intervalAvatar);
return;
}
var avatar = document.getElementsByTagName('aside')[1].children[0].children[0];
if(avatar.children[0] != undefined && avatar.children[0].href != undefined) {
clearInterval(intervalAvatar);
var link = document.createElement('a');
link.id = 'pil_memberPage';
link.href = avatar.children[0].href.replace('member', 'member_illust');
link.appendChild(document.createTextNode('More works'));
avatar.parentNode.insertBefore(link, avatar.nextSibling);
}
}, 200);
}
function addFixedAvatar() {
var avatar = document.getElementsByTagName('aside')[1].children[0].children[0];
var fixedAvatar = document.createElement('div');
fixedAvatar.id = 'pil_fixedAvatar';
fixedAvatar.appendChild(avatar.cloneNode(true));
var links = fixedAvatar.getElementsByTagName('a');
var i = 0;
for(i=0; i < links.length; i++) {
links[i].href = links[i].href.replace('member', 'member_illust');
}
var gallery = document.getElementById('pil_gallery');
if(gallery != undefined) {
gallery.appendChild(fixedAvatar);
}
}
function getSingleOriginalImage(thumb) {
var images = [];
var image = document.createElement('img');
image.src = thumb.href; // original
var imageContainer = document.createElement('div');
if(LOAD_HIGH_RESOLUTION_IMAGES) {
imageContainer.innerHTML = '
';
} else {
image.src = thumb.getElementsByTagName('img')[0].src;
image.dataset.original = thumb.href;
imageContainer.innerHTML = '
';
}
images.push(imageContainer);
fillGallery(images);
}
function getMultipleVerticalOriginalImages() {
var url = unsafeWindow.location.href.replace('medium', 'manga');
var req = new XMLHttpRequest();
req.addEventListener("load", function() {
var images = [];
var parser = new DOMParser();
var responseDoc = parser.parseFromString(this.responseText, "text/html");
var imageContainers = responseDoc.getElementsByClassName('item-container');
if(imageContainers.length == 0) {
getMultipleRtlOriginalImages(responseDoc);
return;
}
var i = 0;
for(i=0; i < imageContainers.length; i++) {
var image = imageContainers[i].getElementsByTagName('img')[0];
image.src = image.dataset.src; //master
var originalSrc = image.src.replace('img-master', 'img-original');
originalSrc = originalSrc.replace('_master1200', '');
image.dataset.original = originalSrc;
var imageContainer = document.createElement('div');
if(LOAD_HIGH_RESOLUTION_IMAGES) {
image.src = originalSrc;
delete image.dataset.original;
var altExt = swapExt(image.src);
imageContainer.innerHTML = '
';
} else {
imageContainer.innerHTML = '
';
}
images.push(imageContainer);
}
fillGallery(images);
});
req.open('GET', url);
req.send();
}
function getMultipleRtlOriginalImages(responseDoc) {
var images = [];
var scriptTags = responseDoc.getElementsByTagName('script');
var i = 0;
for(i=0; i < scriptTags.length; i++) {
if(scriptTags[i].textContent.search('pixiv.context.images\\[') != -1) {
var imageVar = scriptTags[i].textContent.split(';')[0];
var imageUrl = imageVar.split('"')[1].replace(/\\/g, '');
var image = document.createElement('img');
image.src = imageUrl; //master
var originalSrc = image.src.replace('img-master', 'img-original');
originalSrc = originalSrc.replace('_master1200', '');
image.dataset.original = originalSrc;
var imageContainer = document.createElement('div');
if(LOAD_HIGH_RESOLUTION_IMAGES) {
image.src = originalSrc;
delete image.dataset.original;
var altExt = swapExt(image.src);
imageContainer.innerHTML = '
';
} else {
imageContainer.innerHTML = '
';
}
images.push(imageContainer);
}
}
fillGallery(images);
}
function swapExt(src) {
var ext = src.substr(src.length - 3);
var swap = { jpg: 'png', png: 'jpg' };
return src.replace(ext, swap[ext]);
}
function fillGallery(images) {
var gallery = document.createElement('div');
gallery.id = 'pil_gallery';
var i = 0;
for(i=0; i < images.length; i++) {
var p = document.createElement('p');
i++;
var pText = document.createTextNode('Image ' + i + ' of ' + images.length);
i--;
p.appendChild(pText);
gallery.appendChild(p);
//images[i].onclick = function(){ window.close(); }; // OPTIONAL
gallery.appendChild(images[i]);
}
var header = document.getElementsByTagName('header')[0];
header.parentNode.insertBefore(gallery, header.nextSibling);
addFixedAvatar();
}
function getMain() {
// override css
var style = document.createElement('style');
style.type = 'text/css';
var styleCode = `
#pil_gallery {
padding: 3em;
text-align: center;
color: #b3c1d2;
border-bottom: solid 1px white;
margin-bottom: 4em;
background: #ededed;
}
#pil_gallery img {
display: block;
margin: 0 auto 3em auto;
max-width: 100%;
height: auto;
background: #dcdbdb;
`;
if(FIT_IMAGES_TO_SCREEN_WIDTH_AND_HEIGHT) {
styleCode += 'max-height: 90vh';
}
styleCode += `
}
figure > div:nth-child(2) > div {
position: unset !important;
}
#pil_memberPage {
width: 93%;
padding: 0.5em;
background: white;
text-align: center;
display: block;
border-radius: 1em;
margin-top: 1em;
font-weight: bold;
text-decoration: none;
font-size: 80%;
}
#pil_memberPage:visited {
color: #bbb;
}
#pil_fixedAvatar {
text-align: left;
position: fixed;
left: 1.6em;
bottom: 2em;
width: 204px;
z-index: 999;
}
#pil_fixedAvatar a:visited {
color: #bbb;
}
a.stacc_unify_comment_count {
text-align: left !important;
}
.stacc_timeline_bottom {
font-size: 200%;
}
`;
style.innerHTML = styleCode;
document.getElementsByTagName('head')[0].appendChild(style);
// main
var intervalMainCount = 0;
var intervalMain = setInterval(function() {
intervalMainCount++;
if(intervalMainCount >= 300) {
clearInterval(intervalMain);
return;
}
var header = document.getElementsByTagName('header')[0];
if(header != undefined) {
var main = header.nextElementSibling;
if(main != undefined) {
clearInterval(intervalMain);
main.id = 'pil_main';
fire();
var mainObserver = new MutationObserver(fire);
mainObserver.observe(main, {childList: true});
}
}
}, 200);
}
function fire() {
if(document.getElementById('pil_main').children[0].style.display == 'flex') {
return;
}
removeGallery();
// stacc page
if(unsafeWindow.location.href.search('stacc') != -1) {
addLinkToMemberPageAtStaccPage();
}
// illustration page
if(unsafeWindow.location.href.search('medium') != -1) {
displayGallery();
}
}
(function() {
'use strict';
if (window.top != window.self) {
return;
}
getMain();
})();