// ==UserScript==
// @name ImageBoard Viewer/Downloader
// @version 1.46
// @description A simple quick and dirty image viewer various imageboard sites
// @author PineappleLover69
// @include https://gelbooru.com*
// @include https://rule34.xxx*
// @include https://danbooru.donmai*
// @include https://chan.sankakucomplex.com*
// @include https://idol.sankakucomplex.com*
// @include https://rule34hentai.net*
// @connect sankakucomplex.com
// @connect gelbooru.com
// @grant GM_xmlhttpRequest
// @grant GM_download
// @namespace https://greasyfork.org/users/120106
// ==/UserScript==
(function () {
//Settings
var StartImageHeight = 650;
var AutoShowImageView = false;
var DisableImageLinks = true;
var urlChecks = {};
var GetSrcForImg;
var siteObj, defaultSiteObject;
siteObj = siteObj;
SetUpSiteSwitchObjs();
//this group of vars is to be set by SetVars() and depends on the current website
var buttonInsertionPoint, imgList, tagEntry, tagTypeLookup, postsJson, tagArray, postSources;
var tagDictionary = {};
siteObj.SetVars();
siteObj.Startup();
var imgIndex = 0;
var imgOpened = false;
var imgViewBtn = document.createElement("button");
imgViewBtn.innerHTML = "Image View";
imgViewBtn.onclick = ImgView;
var dlAllBtn = document.createElement("button");
dlAllBtn.innerHTML = "Download All";
dlAllBtn.onclick = dlAll;
//imgViewBtn.setAttribute("class", "active");
buttonInsertionPoint.insertBefore(dlAllBtn, buttonInsertionPoint.childNodes[0]);
buttonInsertionPoint.insertBefore(imgViewBtn, buttonInsertionPoint.childNodes[0]);
var imgViewImg, videoImg, preloadImg1, preloadImg2, preloadImg3, preloadImg4;
function ImgView() {
if (imgOpened)
return;
var holdDiv = document.createElement("div");
holdDiv.setAttribute("align", "center");
buttonInsertionPoint.insertBefore(holdDiv, buttonInsertionPoint.childNodes[2]);
imgViewImg = document.createElement("img");
imgViewImg.setAttribute("height", StartImageHeight);
holdDiv.appendChild(imgViewImg);
videoImg = document.createElement("video");
videoImg.setAttribute("height", StartImageHeight);
videoImg.setAttribute("autoplay", true);
videoImg.setAttribute("controls", true);
videoImg.setAttribute("loop", true);
videoImg.setAttribute("hidden", true);
holdDiv.appendChild(videoImg);
preloadImg1 = document.createElement("img");
preloadImg2 = document.createElement("img");
preloadImg1.setAttribute("hidden", true);
preloadImg2.setAttribute("hidden", true);
holdDiv.appendChild(preloadImg1);
holdDiv.appendChild(preloadImg2);
preloadImg3 = document.createElement("img");
preloadImg4 = document.createElement("img");
preloadImg3.setAttribute("hidden", true);
preloadImg4.setAttribute("hidden", true);
holdDiv.appendChild(preloadImg3);
holdDiv.appendChild(preloadImg4);
imgViewImg.addEventListener('load', DoPreload);
imgViewImg.addEventListener('mousedown', ImageMouseDown);
imgViewImg.addEventListener('mouseup', ImageMouseUp);
imgViewImg.addEventListener('mousemove', ImageMouseMove);
imgViewImg.addEventListener('mouseleave', ImageMouseLeave);
videoImg.addEventListener('mousedown', ImageMouseDown);
videoImg.addEventListener('mouseup', ImageMouseUp);
videoImg.addEventListener('mousemove', ImageMouseMove);
videoImg.addEventListener('mouseleave', ImageMouseLeave);
prevBtn = document.createElement("button");
prevBtn.innerHTML = "Prev";
prevBtn.onclick = PrevImg;
nextBtn = document.createElement("button");
nextBtn.innerHTML = "Next";
nextBtn.onclick = NextImg;
dlBtn = document.createElement("button");
dlBtn.innerHTML = "Download";
dlBtn.onclick = DownloadCurrent;
opBtn = document.createElement("button");
opBtn.innerHTML = "Open Src";
opBtn.onclick = OpenSrc;
spacer = document.createElement("img");
spacer.setAttribute("width", 30);
spacer2 = document.createElement("img");
spacer2.setAttribute("width", 30);
spacer3 = document.createElement("img");
spacer3.setAttribute("width", 30);
holdDiv.appendChild(document.createElement("br"));
holdDiv.appendChild(prevBtn);
holdDiv.appendChild(spacer);
holdDiv.appendChild(dlBtn);
holdDiv.appendChild(spacer2);
holdDiv.appendChild(opBtn);
holdDiv.appendChild(spacer3);
holdDiv.appendChild(nextBtn);
siteObj.posts.OnImgView();
imgOpened = true;
let header = document.getElementById("header");
if (header)
header.remove();
header = document.getElementsByClassName("header")[0];
if (header)
header.remove();
document.addEventListener("keydown", keyInput);
SetImg();
}
if (AutoShowImageView)
ImgView();
function TagRequest(tagRequest) {
let xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
let tagPageJson = xmlToJson(this.responseXML);
siteObj.tags.TagDictionarySetup(tagPageJson);
if (imgOpened)
SetNewTags();
}
};
xhttp.open("GET", tagRequest, true);
xhttp.send();
}
function OpenSrc() {
window.open(imgList[imgIndex].getAttribute("openRef"));
}
function ImgClick(e) {
if (!imgOpened)
ImgView();
var parentchildObj = {};
siteObj.ImgClickGetChildAndParent(parentchildObj, e);
// The equivalent of parent.children.indexOf(child)
imgIndex = Array.prototype.indexOf.call(parentchildObj.parent, parentchildObj.child);
SetImg();
imgViewBtn.scrollIntoView();
}
function SetCurrentSrc() {
currentSrc = GetSrcForImg(imgIndex);
//console.log(currentSrc);
}
if (GetSrcForImg == undefined) {
GetSrcForImg = function (getIndex) {
if (postSources[getIndex]) {
return postSources[getIndex];
} else {
var postReq = siteObj.posts.SinglePostSrc(getIndex);
if (postReq == undefined)
return "";
return postReq;
}
};
}
SetNewTags = function () {
if (!tagArray)
return;
siteObj.tags.RemoveTags();
siteObj.tags.AddTags();
siteObj.tags.RemoveEmptyTags();
};
function SetImg() {
SetCurrentSrc();
if (currentSrc == "" || currentSrc == undefined) {
imgViewImg.setAttribute("src", "");
videoImg.setAttribute("src", "");
return;
}
let dI = currentSrc.lastIndexOf(".");
let fileExt = currentSrc.substring(dI + 1).split("?")[0];
if (fileExt.toLowerCase() == "webm" || fileExt.toLowerCase() == "mp4") {
videoImg.setAttribute("src", currentSrc);
videoImg.removeAttribute("hidden");
videoImg.play();
imgViewImg.setAttribute("hidden", true);
setTimeout(DoPreload, 200);
} else {
imgViewImg.setAttribute("src", "");
imgViewImg.removeAttribute("hidden");
videoImg.setAttribute("hidden", true);
videoImg.pause();
setTimeout(SetImageAfterTimeout, 1);
}
SetNewTags();
}
function SetImageAfterTimeout() {
imgViewImg.setAttribute("src", currentSrc);
}
function DoPreload() {
var preIndex = imgIndex + 1;
if (preIndex >= imgList.length)
preIndex = 0;
preloadImg1.src = GetSrcForImg(preIndex);
preIndex++;
if (preIndex >= imgList.length)
preIndex = 0;
preloadImg2.src = GetSrcForImg(preIndex);
preIndex = imgIndex - 1;
if (preIndex < 0)
preIndex = imgList.length - 1;
preloadImg3.src = GetSrcForImg(preIndex);
//preIndex--;
//if(preIndex < 0)
// preIndex = imgList.length - 1;
//preloadImg4.src = GetSrcForImg(preIndex);
}
function DownloadCurrent() {
SetCurrentSrc();
var dI = currentSrc.lastIndexOf(".");
var uI = currentSrc.lastIndexOf("/") + 5;
var fileExt = currentSrc.substring(dI);
var imgName = tagEntry.value + " ";
if (tagEntry.value === "") {
imgName = currentSrc.substring(uI, dI);
} else {
imgName += currentSrc.substring(uI, dI);
}
imgName += " id-" + imgList[imgIndex].childNodes[0].getAttribute("id");
imgName += fileExt;
//GM_download({url: currentSrc, name: imgName, saveAs: false});
//GM_download(currentSrc, imgName);
//console.log(imgName);
//var dl = document.createElement("a");
//dl.setAttribute("href", currentSrc);
//dl.setAttribute("download", imgName);
//dl.style.display = 'none';
//document.body.appendChild(dl);
//dl.click();
//dl.remove();
//document.body.focus();
DownloadFile(currentSrc, imgName);
}
function DownloadFile(source, filename){
GM_xmlhttpRequest({
url: source,
method: 'GET',
context: {
'url': source,
'imgname': filename,
},
responseType: 'blob',
onload: blibBlobDownloader,
});
}
function blibBlobDownloader( xhr )
{
if( xhr.status !== 200 )
{
console.error("xhr.status: ", xhr.status, xhr.statusText);
console.error("url: " + xhr.context.url);
return;
}
var wndURL = window.webkitURL || window.URL,
resource = wndURL.createObjectURL(xhr.response);
fileDownloader(xhr.context.imgname, resource);
wndURL.revokeObjectURL( resource );
}
function fileDownloader( name, resource )
{
var a = document.createElement('a'),
body = document.body || document.getElementsByTagName('body')[0];
a.setAttribute('download', name);
a.href = resource;
body.appendChild(a);
a.click();
body.removeChild(a);
}
function dlAll() {
var prevIndex = imgIndex;
for (imgIndex = 0; imgIndex < imgList.length;) {
try {
DownloadCurrent();
imgIndex++;
} catch (ex) {
console.log(ex);
imgIndex++;
//imgList[imgIndex].remove();
}
}
imgIndex = prevIndex;
}
function keyInput(e) {
if (document.activeElement != tagEntry) {
if (e.keyCode === 32) {
e.preventDefault();
return false;
}
if (e.keyCode === 37) {
e.preventDefault();
PrevImg();
return false;
}
if (e.keyCode === 39) {
e.preventDefault();
NextImg();
return false;
}
if (e.keyCode === 40) {
e.preventDefault();
DownloadCurrent();
return false;
}
}
}
function SetUpSiteSwitchObjs() {
///this is the object that controls what should be done for each individual website supported
defaultSiteObject = {
//the default here serves as a master obj so that code bits can be reused if certain websites
//use similar layouts in areas. it is based on the gelbooru design.
SetVars: function () {
buttonInsertionPoint = document.getElementsByClassName("contain-push")[0];
imgList = document.getElementsByClassName("thumb");
tagEntry = document.getElementById("tags-search");
postSources = Array(imgList.length);
siteObj.posts.RemoveTextFillerElements();
tagTypeLookup = {
0: "tag-type-general",
1: "tag-type-artist",
2: "tag-type-copyright",
3: "tag-type-copyright",
4: "tag-type-character"
};
},
ImgClickGetChildAndParent: function (obj, e) {
obj.child = e.target.parentNode.parentNode;
obj.parent = imgList;
},
GetObjectProperty: function (obj, propName) {
return obj["@attributes"][propName];
},
Startup: function () {
siteObj.posts.DisableImageLinks();
siteObj.posts.BatchPostApiCall();
},
posts: {
postIdReplaceChar: "s",
postLimit: 42,
postPageIdName: "pid",
postLimitName: "limit",
postTagsName: "tags",
postIdName: "id",
postFileUrlName: "file_url",
postApiEndpoint: "/index.php?page=dapi&s=post&q=index",
addSiteNameToFileUrl: false,
OnImgView: function () {
},
DisableImageLinks: function () {
for (let i = 0; i < imgList.length;) {
try {
if (!imgList[i].getAttribute("openRef")) {
let tmpAnchor = imgList[i].childNodes[0];
imgList[i].setAttribute("openRef", tmpAnchor.getAttribute("href"));
if (DisableImageLinks) {
tmpAnchor.onclick = null;
tmpAnchor.removeAttribute("onclick");
tmpAnchor.removeAttribute("href");
tmpAnchor.addEventListener("click", ImgClick);
}
}
i++;
} catch (ex) {
imgList[i].remove();
}
}
},
RemoveTextFillerElements: function () {
for (let i = 0; i < imgList.length;) {
if (imgList[i].tagName === undefined) {
imgList[i].remove();
} else {
i++;
}
}
},
BatchPostApiCall: function () {
var apiCallObj = getJsonFromUrl();
siteObj.posts.PostApiSelector(apiCallObj);
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
postsJson = xmlToJson(this.responseXML);
siteObj.posts.PostSourcesSelector(apiCallObj);
siteObj.tags.CreateTagBase();
}
};
xhttp.open("GET", apiCallObj.request, true);
xhttp.send();
},
HandlePageId: function (value) {
return value / this.postLimit;
},
PostApiSelector: function (apiObj) {
let pid = 0;
apiObj.postLimit = this.postLimit;
if (apiObj[this.postPageIdName]) {
pid = this.HandlePageId(apiObj[this.postPageIdName]);
}
let tags = encodeUriSpecial(tagEntry.value);
apiObj.request = this.postApiEndpoint + "&" + this.postLimitName + "=" + apiObj.postLimit
+ "&" + this.postTagsName + "=" + tags + "&" + this.postPageIdName + "=" + pid;
},
PostsJsonGetPost: function (index) {
let tmpPost = postsJson.posts.post[index];
return tmpPost;
},
PostMismatch: function (apiObj, index) {
imgList[index].remove();
imgList[imgList.length - 1].remove();
apiObj.postLimit -= 2;
console.log("removed 1: " + apiObj.postLimit + " : " + imgList.length);
},
PostSourcesSelector: function (apiObj) {
apiObj.postOffset = 0;
for (let i = 0; i < apiObj.postLimit;) {
let tmpPost = siteObj.posts.PostsJsonGetPost(i + apiObj.postOffset);
if (!tmpPost)
break;
let tmpId = imgList[i].id;
tmpId = tmpId.replace(this.postIdReplaceChar, "");
if (siteObj.GetObjectProperty(tmpPost, "id") != tmpId) {
siteObj.posts.PostMismatch(apiObj, i);
} else {
postSources[i] = siteObj.GetObjectProperty(tmpPost, this.postFileUrlName);
if (siteObj.posts.addSiteNameToFileUrl)
postSources[i] = window.location.hostname + postSources[i];
i++;
}
}
},
GetSinglePostApiRequest: function (tmpId) {
let request = JsonHttpRequest(this.postApiEndpoint + "&" + this.postIdName + "=" + tmpId.toString());
return siteObj.GetObjectProperty(request, this.postFileUrlName);
},
SinglePostSrc: function (getIndex) {
var tmpId = imgList[getIndex][this.postIdName];
tmpId = tmpId.replace(this.postIdReplaceChar, "");
var tmpSrc = siteObj.posts.GetSinglePostApiRequest(tmpId);
postSources[getIndex] = tmpSrc;
return tmpSrc;
}
},
tags: {
tagApiEndpoint: "/index.php?page=dapi&s=tag&q=index&names=",
maxTagApiCount: 99,
logTagErrors: true,
tagApiSplitChar: " ",
tagsSplitChar: " ",
tagsPropertyName: "tags",
tagCategoryPropertyName: "type",
tagCountPropertyName: "count",
tagNamePropertyName: "name",
GetTagSidebarElement: function () {
return document.getElementById("searchTags");
},
CreateTagBase: function () {
let uniqueTagList = [];
siteObj.tags.GetSplitTagsPerPost(uniqueTagList);
uniqueTagList = mergeDedupe(uniqueTagList);
siteObj.tags.TagApiSelector(uniqueTagList);
},
GetSplitTagsPerPost: function (uniqueTagList) {
for (var i = 0; i < imgList.length; i++) {
var currentPost = siteObj.posts.PostsJsonGetPost(i);
var tags = siteObj.GetObjectProperty(currentPost, this.tagsPropertyName).toLowerCase();
var splitTags = tags.split(this.tagsSplitChar);
uniqueTagList.push(splitTags);
}
},
TagApiSelector: function (uniqueTagList) {
var uniqueTagString = "";
var uniqueStringArray = [];
var usCount = 0;
for (i = 0; i < uniqueTagList.length; i++) {
if (usCount === 0) {
uniqueTagString += uniqueTagList[i];
} else {
uniqueTagString += this.tagApiSplitChar + uniqueTagList[i];
}
usCount++;
if (usCount > this.maxTagApiCount || i == uniqueTagList.length - 1) {
usCount = 0;
uniqueStringArray.push(uniqueTagString);
uniqueTagString = "";
}
}
for (i = 0; i < uniqueStringArray.length; i++) {
let request = this.tagApiEndpoint + encodeUriSpecial(uniqueStringArray[i]);
TagRequest(request);
}
},
GetTagJsonArray: function (tagJson) {
return tagJson.tags.tag;
},
TagDictionarySetup: function (tagsJson) {
let tmpArray = siteObj.tags.GetTagJsonArray(tagsJson);
if (!tagArray)
tagArray = tmpArray;
else {
tagArray = tagArray.concat(tmpArray);
}
for (i = 0; i < tmpArray.length; i++) {
tagDictionary[siteObj.GetObjectProperty(tmpArray[i], this.tagNamePropertyName).toLowerCase()] = tmpArray[i];
}
},
GetNodeIndex: function () {
return (window.location.hostname == "rule34.xxx") ? 4 : 7;
},
TagCountFormatter: function (count) {
var nCount = Number(count);
return nCount;
},
TagCloneNameSetter: function (tagClone, tagName) {
let nodeIndex = siteObj.tags.GetNodeIndex();
tagClone.childNodes[nodeIndex].innerHTML = tagName.replace(/_/g, " ");
},
TagCloneCountSetter: function (tagClone, tagCount) {
let nodeIndex = siteObj.tags.GetNodeIndex();
tagClone.childNodes[nodeIndex + 2].innerHTML = siteObj.tags.TagCountFormatter(tagCount);
},
AddTag: function (tagName, tagParent, tagToClone, stringToReplace) {
try {
var clonedTag = tagToClone.cloneNode(true);
tagParent.appendChild(clonedTag);
clonedTag.innerHTML = clonedTag.innerHTML.replaceAll("class=", "cla$$=");
clonedTag.innerHTML = clonedTag.innerHTML.replaceAll(stringToReplace, encodeUriSpecial(tagName));
clonedTag.innerHTML = clonedTag.innerHTML.replaceAll("cla$$=", "class=");
siteObj.tags.TagCloneNameSetter(clonedTag, tagName);
var jsonTag = tagDictionary[tagName];
var tagType = siteObj.GetObjectProperty(jsonTag, this.tagCategoryPropertyName);
var tagCount = siteObj.GetObjectProperty(jsonTag, this.tagCountPropertyName);
clonedTag.setAttribute("class", tagTypeLookup[tagType]);
siteObj.tags.TagCloneCountSetter(clonedTag, tagCount);
} catch (ex) {
if (this.logTagErrors) {
console.log("Failed tag: " + tagName);
console.log(ex);
console.log(tagDictionary);
}
}
},
FindStringToReplace: function (tag) {
let nodeIndex = siteObj.tags.GetNodeIndex();
return encodeUriSpecial(tag.childNodes[nodeIndex].innerHTML);
},
AddTags: function () {
let currentPost = siteObj.posts.PostsJsonGetPost(imgIndex);
let tags = siteObj.GetObjectProperty(currentPost, this.tagsPropertyName);
let splitTags = tags.split(this.tagsSplitChar);
let tagBar = siteObj.tags.GetTagSidebarElement();
let firstTag = tagBar.childNodes[0];
//let stringToReplace = firstTag.innerHTML.substring(firstTag.innerHTML.lastIndexOf("tags=") + 5, firstTag.innerHTML.lastIndexOf('</a>') - 3);
let stringToReplace = siteObj.tags.FindStringToReplace(firstTag).replace("%20", "_");
for (let i = 0; i < splitTags.length; i++) {
siteObj.tags.AddTag(splitTags[i], tagBar, firstTag, stringToReplace);
}
firstTag.remove();
},
RemoveTags: function () {
let tagBar = siteObj.tags.GetTagSidebarElement();
if (tagBar.childNodes[0].innerHTML === undefined) {
tagBar.childNodes[0].remove();
}
for (let i = tagBar.childNodes.length - 1; i >= 1; i--) {
tagBar.childNodes[i].remove();
}
},
RemoveEmptyTags: function () {
let tagBar = siteObj.tags.GetTagSidebarElement();
for (let i = tagBar.childNodes.length - 1; i >= 0; i--) {
let tAg = tagBar.childNodes[i];
try {
if (tAg.childNodes[4].innerHTML === "" || tAg.childNodes[7].innerHTML === "") {
tAg.remove();
}
} catch (ex) {
}
}
}
}
};
siteObj = cloneObject(defaultSiteObject);
let hostName = window.location.hostname;
//console.log(hostName + " : " + ());
if (hostName.startsWith("danbooru.donmai"))
hostName = "danbooru.donmai";
if (hostName == "idol.sankakucomplex.com")
hostName = "chan.sankakucomplex.com";
//console.log(hostName);
switch (hostName) {
case "gelbooru.com":
let tagBar = siteObj.tags.GetTagSidebarElement();
let tagParent = tagBar.parentNode;
tagParent.insertBefore(tagBar.childNodes[0], tagBar);
tagParent.insertBefore(tagBar.childNodes[0], tagBar);
tagParent.insertBefore(tagBar.childNodes[0], tagBar);
tagParent.insertBefore(tagBar.childNodes[0], tagBar);
tagParent.insertBefore(tagBar.childNodes[0], tagBar);
break;
case "rule34.xxx":
siteObj.tags.logTagErrors = false;
siteObj.tags.GetTagSidebarElement = function () {
return document.getElementById("tag-sidebar");
};
siteObj.SetVars = function () {
buttonInsertionPoint = document.getElementsByClassName("content")[0];
imgList = document.getElementsByClassName("thumb");
tagEntry = document.getElementById("tags");
postSources = Array(imgList.length);
siteObj.posts.RemoveTextFillerElements();
tagTypeLookup = {
0: "tag-type-general",
1: "tag-type-artist",
2: "tag-type-copyright",
3: "tag-type-copyright",
4: "tag-type-character"
};
};
break;
case "danbooru.donmai":
siteObj.SetVars = function () {
buttonInsertionPoint = document.getElementById("post-sections");
var postList = document.getElementById("posts");
imgList = postList.childNodes[1].childNodes;
tagEntry = document.getElementById("tags");
postSources = Array(imgList.length);
siteObj.posts.RemoveTextFillerElements();
tagTypeLookup = {
0: "category-0",
1: "category-1",
2: "category-2",
3: "category-3",
4: "category-4"
};
};
//danbooru post stuff
siteObj.posts.postPageIdName = "page";
siteObj.posts.postIdReplaceChar = "post_";
siteObj.posts.postFileUrlName = "large-file-url";
siteObj.posts.postApiEndpoint = "/posts.xml?";
siteObj.posts.postLimit = 20;
siteObj.posts.HandlePageId = function (value) {
return Number(value);
};
siteObj.GetObjectProperty = function (obj, propName) {
return obj[propName]["#text"];
};
siteObj.posts.GetSinglePostApiRequest = function (tmpId) {
let request = JsonHttpRequest("/posts/" + tmpId.toString() + ".xml?");
return siteObj.GetObjectProperty(request, siteObj.posts.postFileUrlName);
};
siteObj.posts.PostMismatch = function (apiObj, index) {
console.log(postsJson);
//imgList[index].remove();
apiObj.postLimit--;
apiObj.postOffset++;
console.log("removed 1: " + apiObj.postLimit + " : " + imgList.length);
};
//danbooru tag stuff
siteObj.tags.tagApiEndpoint = "/tags.xml?search[name]=";
siteObj.tags.tagApiSplitChar = ",";
siteObj.tags.tagsPropertyName = "tag-string";
siteObj.tags.tagCategoryPropertyName = "category";
siteObj.tags.tagCountPropertyName = "post-count";
siteObj.tags.maxTagApiCount = 19;
siteObj.tags.GetTagSidebarElement = function () {
return document.getElementById("tag-box").childNodes[3];
};
siteObj.tags.FindStringToReplace = function (tag) {
let tmpStr = tag.childNodes[2].innerHTML.replace(/ /g, "_");
return encodeUriSpecial(tmpStr);
};
siteObj.tags.TagCloneNameSetter = function (tagClone, tagName) {
tagClone.childNodes[2].innerHTML = tagName.replace(/_/g, " ");
};
siteObj.tags.TagCountFormatter = function (count) {
var nCount = Number(count);
if (nCount < 1000) {
return nCount.toString();
} else if (nCount < 10000) {
return (nCount / 1000).toPrecision(2).toString() + "k";
} else {
nCount /= 1000;
return Math.round(nCount).toString() + "k";
}
};
siteObj.tags.TagCloneCountSetter = function (tagClone, tagCount) {
tagClone.childNodes[4].innerHTML = siteObj.tags.TagCountFormatter(tagCount);
};
break;
case "rule34hentai.net":
document.addEventListener("mousemove", function () {
console.log("horg");
});
siteObj.SetVars = function () {
buttonInsertionPoint = document.getElementById("imagelist").parentNode;
imgList = document.getElementsByClassName("thumb");
tagEntry = $('#Navigationleft > div > form > ul > li > input')[0];
postSources = Array(imgList.length);
siteObj.posts.RemoveTextFillerElements();
//buttonInsertionPoint = document.body;
};
GetSrcForImg = function (getIndex) {
let tmpImg = imgList[getIndex];
let srcIndex = tmpImg.childNodes[0].src;
let postId = tmpImg.getAttribute('data-post-id');
let postTags = tmpImg.getAttribute('data-post-id');
let postType = tmpImg.childNodes[0].getAttribute('title');
postType = postType.substring(postType.lastIndexOf("// ") + 3);
let imgSrc = srcIndex.replace("_thumbs", "_images").replace("thumb.jpg", postId + ' - ' + postTags + '.' + postType);
console.log(imgSrc);
return imgSrc;
};
let tImgClick = function(e) {
if (!imgOpened)
ImgView();
var parentchildObj = {};
parentchildObj.child = e.target.parentNode;
parentchildObj.parent = imgList;
// The equivalent of parent.children.indexOf(child)
imgIndex = Array.prototype.indexOf.call(parentchildObj.parent, parentchildObj.child);
console.log(imgIndex);
imgViewBtn.scrollIntoView();
SetImg();
}
siteObj.posts.DisableImageLinks = function () {
for (let i = 0; i < imgList.length;) {
try {
if (!imgList[i].getAttribute("openRef")) {
let tmpAnchor = imgList[i];
imgList[i].setAttribute("openRef", tmpAnchor.getAttribute("href"));
if (DisableImageLinks) {
tmpAnchor.onclick = null;
tmpAnchor.removeAttribute("onclick");
tmpAnchor.removeAttribute("href");
tmpAnchor.addEventListener("click", tImgClick);
}
}
i++;
} catch (ex) {
imgList[i].remove();
}
}
}
//siteObj.posts.BatchPostApiCall = function () {
// siteObj.posts.DisableImageLinks();
// //let tCount = 0;
// //for (let i = 0; i < imgList.length; i++) {
// // let tSrc = siteObj.posts.SinglePostSrc(i);
// // if(tSrc !== undefined){
// // tCount++;
// // }
// //}
// //console.log(tCount + "/" + imgList.length);
//};
break;
case "chan.sankakucomplex.com":
//sankaku posts stuff
document.addEventListener("mousemove", function () {
siteObj.posts.BatchPostApiCall();
});
siteObj.SetVars = function () {
buttonInsertionPoint = document.getElementsByClassName("content")[0];
imgList = document.getElementsByClassName("thumb");
tagEntry = document.getElementById("tags");
postSources = Array(imgList.length);
siteObj.posts.RemoveTextFillerElements();
tagTypeLookup = {
0: "tag-type-general",
1: "tag-type-artist",
2: "tag-type-copyright",
3: "tag-type-copyright",
4: "tag-type-character"
};
postSources = {};
if (document.getElementById("recommended"))
buttonInsertionPoint = document.getElementById("recommended");
};
GetSrcForImg = function (getIndex) {
let tmpImg = imgList[getIndex].childNodes[0].childNodes[0];
let srcIndex = tmpImg.src;
if (postSources[srcIndex]) {
return postSources[srcIndex];
} else {
var postReq = siteObj.posts.SinglePostSrc(getIndex);
if (postReq == undefined)
return "";
return postReq;
}
};
let redirectCheck = function (response) {
//console.log("rdc: " + response.finalUrl);
return !response.finalUrl.includes("redirect.png");
};
siteObj.posts.SinglePostSrc = function (index) {
let tmpImg = imgList[index].childNodes[0].childNodes[0];
let srcIndex = tmpImg.src;
let tImg = imgList[index];
let postUrl = tImg.getAttribute('openref');
let postHtml = GetHtmlFromUrl(postUrl);
let imageSrc = postHtml.substring(postHtml.indexOf('Original: <a href="') + 19);
//imageSrc = imageSrc.substring(imageSrc.indexOf('src="')+5, imageSrc.indexOf('>'));
imageSrc = 'http:' + imageSrc.substring(0, imageSrc.indexOf('"')).replace('&', '&');
postSources[srcIndex] = imageSrc;
return postSources[srcIndex];
//old
if (postSources[srcIndex] === undefined) {
let tmpUrl = tmpImg.src;
tmpUrl = tmpUrl.replace("/preview/", "/").replace("c.sank", "cs.sank").replace("i.sank", "is.sank");
tmpUrl = tmpUrl.substring(0, tmpUrl.lastIndexOf("."));
let tmpId = "?" + imgList[index].id.substring(1);
let tmpTags = tmpImg.getAttribute("title");
tmpTags = tmpTags.substring(0, tmpTags.lastIndexOf("Rating:"));
if (tmpTags.includes("animated") || tmpTags.includes("video") || tmpTags.includes("mp4") || tmpTags.includes("webm") || tmpTags.includes("animated_gif")) {
if (tmpTags.includes("mp4")) {
//AsyncUrlCheck(tmpUrl + ".mp4", index, redirectCheck);
postSources[srcIndex] = tmpUrl + ".mp4" + tmpId;
} else if (tmpTags.includes("webm")) {
//AsyncUrlCheck(tmpUrl + ".webm", index, redirectCheck);
postSources[srcIndex] = tmpUrl + ".webm" + tmpId;
} else if (tmpTags.includes("animated_gif")) {
//AsyncUrlCheck(tmpUrl + ".gif", index, redirectCheck);
postSources[srcIndex] = tmpUrl + ".gif" + tmpId;
} else {
NoApiFindUrlAsync(index, srcIndex, tmpUrl, true, tmpId, redirectCheck);
}
return postSources[srcIndex];
} else {
NoApiFindUrlAsync(index, srcIndex, tmpUrl, false, tmpId, redirectCheck);
}
} else {
return postSources[srcIndex];
}
};
siteObj.posts.BatchPostApiCall = function () {
siteObj.posts.DisableImageLinks();
//let tCount = 0;
//for (let i = 0; i < imgList.length; i++) {
// let tSrc = siteObj.posts.SinglePostSrc(i);
// if(tSrc !== undefined){
// tCount++;
// }
//}
//console.log(tCount + "/" + imgList.length);
};
break;
}
//end switch setup
}
//----------everything below here is either utility or is pretty set in stone-------------------
function encodeUriSpecial(str) {
return encodeURIComponent(str).replace(/\(/g, "%28").replace(/\)/g, "%29");
}
Element.prototype.remove = function () {
if (this)
this.parentElement.removeChild(this);
};
//String.prototype.replaceAll = function (search, replacement) {
// var target = this;
// return target.replace(new RegExp(search, 'g'), replacement);
//};
String.prototype.replaceAll = function (search, replacement) {
var target = this;
return target.split(search).join(replacement);
};
function mergeDedupe(arr) {
return [...new Set([].concat(...arr))];
}
function PrevImg() {
imgIndex--;
if (imgIndex < 0)
imgIndex = imgList.length - 1;
SetImg();
}
function NextImg() {
imgIndex++;
if (imgIndex >= imgList.length)
imgIndex = 0;
SetImg();
}
var imgMouseDown = false;
var imgDownPosX, imgDownPosY, imgDownHeight = 0;
function ImageMouseDown(e) {
e.preventDefault();
imgMouseDown = true;
imgDownPosX = e.screenX;
imgDownPosY = e.screenY;
imgDownHeight = Number(imgViewImg.getAttribute("height"));
return false;
}
function ImageMouseUp(e) {
e.preventDefault();
imgMouseDown = false;
return false;
}
function ImageMouseMove(e) {
if (imgMouseDown) {
e.preventDefault();
var moveDist = e.screenY - Number(imgDownPosY);
imgViewImg.setAttribute("height", imgDownHeight + moveDist * 2);
videoImg.setAttribute("height", imgDownHeight + moveDist * 2);
return false;
}
}
function ImageMouseLeave(e) {
e.preventDefault();
imgMouseDown = false;
return false;
}
function getJsonFromUrl() {
var query = location.search.substr(1);
var result = {};
query.split("&").forEach(function (part) {
var item = part.split("=");
result[item[0]] = decodeURIComponent(item[1]);
});
return result;
}
function cloneObject(obj) {
if (obj === null || typeof obj !== 'object') {
return obj;
}
let temp = obj.constructor(); // give temp the original obj's constructor
for (let key in obj) {
temp[key] = cloneObject(obj[key]);
}
return temp;
}
function AsyncHtmlDocHandler(index, callback) {
try {
let url = imgList[index].getAttribute("openRef");
var xhr = new XMLHttpRequest();
xhr.onload = function () {
if (this.status = 200 && this.readyState == 4 && callback && typeof( callback ) === 'function') {
callback(this.response);
}
};
xhr.open('GET', url);
xhr.responseType = 'document';
xhr.send();
} catch (ex) {
}
}
function NoApiFindUrlAsync(index, srcIndex, url, checkAnimated = false, append = "", extraCheck = function (r) {
return true;
}) {
if (urlChecks[url])
return;
urlChecks[url] = {
jpg: null,
jpeg: null,
png: null,
gif: null,
mp4: null,
webm: null,
abortAll: function () {
if (this.jpg)
this.jpg.abort();
if (this.jpeg)
this.jpeg.abort();
if (this.png)
this.png.abort();
if (this.gif)
this.gif.abort();
if (this.mp4)
this.mp4.abort();
if (this.webm)
this.webm.abort();
jpg = null;
jpeg = null;
png = null;
gif = null;
mp4 = null;
webm = null;
}
};
if (!checkAnimated) {
AsyncUrlCheck(url, append, index, srcIndex, "jpg", extraCheck,);
AsyncUrlCheck(url, append, index, srcIndex, "jpeg", extraCheck);
AsyncUrlCheck(url, append, index, srcIndex, "png", extraCheck);
} else {
AsyncUrlCheck(url, append, index, srcIndex, "mp4", extraCheck);
AsyncUrlCheck(url, append, index, srcIndex, "gif", extraCheck);
AsyncUrlCheck(url, append, index, srcIndex, "webm", extraCheck);
}
}
function AsyncUrlCheck(url, append, index, srcIndex, ext, extraCheck) {
let modUrl = url + "." + ext + append;
try {
urlChecks[url][ext] = GM_xmlhttpRequest({
method: "HEAD",
url: modUrl,
onreadystatechange: function (response) {
if (response.status == 0)
return;
if (response.status == 200 && extraCheck(response)) {
//urlChecks[url] = false;
//console.log(response.readyState +" : " + response.status + " : " + response.finalUrl);
console.log("got: " + modUrl);
postSources[srcIndex] = modUrl;
if (imgOpened && imgIndex == index) {
SetImg();
}
urlChecks[url].abortAll();
} else if (response.status == 404) {
console.log("not found: " + modUrl);
urlChecks[url][ext].abort();
} else {
console.log("something else: " + response.status + " : " + response.readyState + " : " + response.finalUrl);
urlChecks[url] = null;
}
}
});
} catch (ex) {
console.log(ex);
urlChecks[url] = null;
}
}
function GetHtmlFromUrl(url){
var xhr = new XMLHttpRequest();
xhr.open("GET", url, false);
xhr.send();
//xhr.onreadystatechange = function(){
//
//}
return xhr.response;
}
function JsonHttpRequest(urlRequest) {
var xhr = new XMLHttpRequest();
xhr.open("GET", urlRequest, false);
xhr.send();
return xmlToJson(xhr.responseXML);
}
// Changes XML to JSON
function xmlToJson(xml) {
// Create the return object
var obj = {};
if (xml.nodeType == 1) { // element
// do attributes
if (xml.attributes.length > 0) {
obj["@attributes"] = {};
for (var j = 0; j < xml.attributes.length; j++) {
var attribute = xml.attributes.item(j);
obj["@attributes"][attribute.nodeName] = attribute.nodeValue;
}
}
} else if (xml.nodeType == 3) { // text
obj = xml.nodeValue;
}
// do children
if (xml.hasChildNodes()) {
for (var i = 0; i < xml.childNodes.length; i++) {
var item = xml.childNodes.item(i);
var nodeName = item.nodeName;
if (typeof(obj[nodeName]) == "undefined") {
obj[nodeName] = xmlToJson(item);
} else {
if (typeof(obj[nodeName].push) == "undefined") {
var old = obj[nodeName];
obj[nodeName] = [];
obj[nodeName].push(old);
}
obj[nodeName].push(xmlToJson(item));
}
}
}
return obj;
}
})
();