// ==UserScript==
// @name NHentai Improved
// @namespace Hentiedup
// @version 1.7.0
// @description Partially fade/remove non-english, HQ thumbnails, mark as read, subs, version grouping etc.
// @author Hentiedup
// @match https://nhentai.net/*
// @require https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_deleteValue
// @grant GM_listValues
// @icon https://i.imgur.com/1lihxY2.png
// ==/UserScript==
(function() {
'use strict';
//YOU SHOULD NOT TOUCH THE SETTINGS HERE. THEY ARE NOW AVAILABLE ON THE SITE IN THE PROFILE SETTINGS
//== non-english settings ==//
var remove_non_english = GM_getValue("remove_non_english", false);
var partially_fade_all_non_english = GM_getValue("partially_fade_all_non_english", true);
var non_english_fade_opacity = GM_getValue("non_english_fade_opacity", 0.3);
//== browse sections ==//
var browse_thumbnail_width = GM_getValue("browse_thumbnail_width", 250);
var browse_thumnail_container_width = GM_getValue("browse_thumnail_container_width", 1350);
var load_high_quality_browse_thumbnails = GM_getValue("load_high_quality_browse_thumbnails", true);
//== comic pages view ==//
var pages_thumbnail_width = GM_getValue("pages_thumbnail_width", 300);
var pages_thumnail_container_width = GM_getValue("pages_thumnail_container_width", 1350);
var load_high_quality_pages_thumbnails = GM_getValue("load_high_quality_pages_thumbnails", true);
var max_image_reload_attempts = 20;
//== mark as read system ==//
var mark_as_read_system_enabled = GM_getValue("mark_as_read_system_enabled", true);
var marked_as_read_fade_opacity = GM_getValue("marked_as_read_fade_opacity", 0.3);
var read_tag_font_size = GM_getValue("read_tag_font_size", 15);
//== subscription system ==//
var subscription_system_enabled = GM_getValue("subscription_system_enabled", true);
//== version grouping system ==//
var version_grouping_enabled = GM_getValue("version_grouping_enabled", true);
var version_grouping_filter_brackets = GM_getValue("version_grouping_filter_brackets", false);
var auto_group_on_page_comics = GM_getValue("auto_group_on_page_comics", true);
var flagEn = "https://i.imgur.com/vSnHmmi.gif";
var flagJp = "https://i.imgur.com/GlArpuS.gif";
var flagCh = "https://i.imgur.com/7B55DYm.gif";
//== comic reader system ==//
var comic_reader_improved_zoom = GM_getValue("comic_reader_improved_zoom", true);
//== tag blocking system ==//
var tag_blocking_enabled = GM_getValue("tag_blocking_enabled", true);
var BlockTagArray = [];
var BlockTagArrayString = GM_getValue("BlockTagArrayString", null);
if(BlockTagArrayString) { BlockTagArray = JSON.parse(BlockTagArrayString); }
var banIcon = `<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="ban" class="svg-inline--fa fa-ban fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M256 8C119.034 8 8 119.033 8 256s111.034 248 248 248 248-111.034 248-248S392.967 8 256 8zm130.108 117.892c65.448 65.448 70 165.481 20.677 235.637L150.47 105.216c70.204-49.356 170.226-44.735 235.638 20.676zM125.892 386.108c-65.448-65.448-70-165.481-20.677-235.637L361.53 406.784c-70.203 49.356-170.226 44.736-235.638-20.676z"></path></svg>`;
//================= Getting arrays ready =================//
if(true) {
if(subscription_system_enabled) {
var SubArray = [];
var SubArrayString = GM_getValue("SubArrayString", null);
if(SubArrayString) { SubArray = JSON.parse(SubArrayString); }
}
if(mark_as_read_system_enabled) {
var MARArray = [];
var MARArrayString = GM_getValue("MARArrayString", null);
if(MARArrayString) { MARArray = JSON.parse(MARArrayString); }
var unreadImg = '<svg style="vertical-align: middle;" width="15" height="15" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="book-open" class="svg-inline--fa fa-book-open fa-w-18" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path fill="currentColor" d="M542.22 32.05c-54.8 3.11-163.72 14.43-230.96 55.59-4.64 2.84-7.27 7.89-7.27 13.17v363.87c0 11.55 12.63 18.85 23.28 13.49 69.18-34.82 169.23-44.32 218.7-46.92 16.89-.89 30.02-14.43 30.02-30.66V62.75c.01-17.71-15.35-31.74-33.77-30.7zM264.73 87.64C197.5 46.48 88.58 35.17 33.78 32.05 15.36 31.01 0 45.04 0 62.75V400.6c0 16.24 13.13 29.78 30.02 30.66 49.49 2.6 149.59 12.11 218.77 46.95 10.62 5.35 23.21-1.94 23.21-13.46V100.63c0-5.29-2.62-10.14-7.27-12.99z"></path></svg>';
var readImg = '<svg style="vertical-align: middle;" width="15" height="15" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="book" class="svg-inline--fa fa-book fa-w-14" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path fill="currentColor" d="M448 360V24c0-13.3-10.7-24-24-24H96C43 0 0 43 0 96v320c0 53 43 96 96 96h328c13.3 0 24-10.7 24-24v-16c0-7.5-3.5-14.3-8.9-18.7-4.2-15.4-4.2-59.3 0-74.7 5.4-4.3 8.9-11.1 8.9-18.6zM128 134c0-3.3 2.7-6 6-6h212c3.3 0 6 2.7 6 6v20c0 3.3-2.7 6-6 6H134c-3.3 0-6-2.7-6-6v-20zm0 64c0-3.3 2.7-6 6-6h212c3.3 0 6 2.7 6 6v20c0 3.3-2.7 6-6 6H134c-3.3 0-6-2.7-6-6v-20zm253.4 250H96c-17.7 0-32-14.3-32-32 0-17.6 14.4-32 32-32h285.4c-1.9 17.1-1.9 46.9 0 64z"></path></svg>';
}
}
//========================================================//
//================== Adding stylesheets ==================//
if(true) {
if(remove_non_english) {
addGlobalStyle(`
.gallery:not([data-tags~='12227']) {
display: none;
}
`);
}
else if(!remove_non_english && partially_fade_all_non_english) {
addGlobalStyle(`
.gallery:not([data-tags~='12227']) > .cover > img, .gallery:not([data-tags~='12227']) > .cover > .caption{
opacity: ` + non_english_fade_opacity + `;
}
`);
}
if(mark_as_read_system_enabled)
{
let MARArraySelector = "";
for(let i = 0; i < MARArray.length; i++)
MARArraySelector += `.cover[href="`+MARArray[i]+`"] > img, .cover[href="`+MARArray[i]+`"] > .caption, `;
MARArraySelector = MARArraySelector.substr(0, MARArraySelector.length-2);
addGlobalStyle(`
`+MARArraySelector+`
{
opacity: `+marked_as_read_fade_opacity+`;
}
`);
}
if(tag_blocking_enabled) {
let blockedTagsStylingString = "";
for(let i = 0; i < BlockTagArray.length; i++)
{
blockedTagsStylingString += "html.theme-black a.tag.tag-" + BlockTagArray[i][0] + " > span" +
", html.theme-black a.tag.tag-" + BlockTagArray[i][0] + ":hover" + " > span" +
", html.theme-black a.tag.tag-" + BlockTagArray[i][0] + ":active" + " > span" +
", html.theme-black a.tag.tag-" + BlockTagArray[i][0] + ":focus" + " > span" +
", a.tag.tag-" + BlockTagArray[i][0] + " > span" +
", a.tag.tag-" + BlockTagArray[i][0] + ":hover" + " > span" +
", a.tag.tag-" + BlockTagArray[i][0] + ":active" + " > span" +
", a.tag.tag-" + BlockTagArray[i][0] + ":focus" + " > span";
if(i < BlockTagArray.length-1)
blockedTagsStylingString += ", ";
}
//console.log(BlockTagArray);
//console.log(blockedTagsStylingString);
addGlobalStyle(`
`+blockedTagsStylingString+` {
background-color: #500;
}
.blockTagButton
{
display: inline-block;
width: 13px;
height: 13px;
vertical-align: middle;
cursor: pointer;
margin-left: 2px;
}
.blockTagButton > svg
{
vertical-align: top;
color: #ff5454;
width: 13px;
height: 13px;
}
.blockTagButton:active > svg, .blockTagButton:hover > svg, .blockTagButton:focus > svg
{
color: #822B2B;
}
`);
}
//fixing too long cover images
addGlobalStyle(`
.gallery, .gallery > .cover {
max-height: `+(browse_thumbnail_width*1.42)+`px;
}
.gallery > .cover {
overflow: hidden;
padding: 0 !important;
}
.gallery > .cover > img {
position: relative;
min-height: 100%;
}
`);
addGlobalStyle(`
/*browsing comics*/
.container.index-container, #favcontainer {
text-align: center;
max-width: 100%;
width: ` + browse_thumnail_container_width + `px;
}
.gallery > .cover > img {
width: 100%;
}
.container.index-container > div.gallery, #favcontainer > .gallery-favorite {
width: ` + browse_thumbnail_width + `px;
}
/*view comic pages*/
div.thumb-container {
width: auto;
}
#thumbnail-container {
text-align: center;
max-width: 100%;
width: ` + pages_thumnail_container_width + `px;
}
div.thumb-container img {
width: ` + pages_thumbnail_width + `px;
}
`);
if(version_grouping_enabled)
{
addGlobalStyle(`
.overlayFlag
{
position: absolute;
display: inline-block;
top: 3px;
left: 3px;
z-index: 3;
width: 18px;
height: 12px;
}
.numOfVersions {
border-radius: 10px;
padding: 5px 10px;
position: absolute;
background-color: rgba(0,0,0,.7);
color: rgba(255,255,255,.8);
top: 7.5px;
left: 105px;
font-size: 12px;
font-weight: 900;
opacity: 1;
width: 40px;
z-index: 2;
display: none;
}
.findVersionButton {
border-radius: 10px;
padding: 5px 10px;
position: absolute;
background-color: rgba(0,0,0,.4);
color: rgba(255,255,255,.8);
bottom: 7.5px;
left: 7.5px;
font-size: 12px;
font-weight: 900;
opacity: 1;
width: 125px;
z-index: 2;
cursor: pointer;
}
.versionNextButton {
border-radius: 10px;
padding: 5px 10px;
position: absolute;
background-color: rgba(0,0,0,.7);
color: rgba(255,255,255,.8);
top: 7.5px;
right: 7.5px;
font-size: 12px;
font-weight: 900;
opacity: 1;
display: none;
z-index: 2;
cursor: pointer;
}
.versionPrevButton {
border-radius: 10px;
padding: 5px 10px;
position: absolute;
background-color: rgba(0,0,0,.7);
color: rgba(255,255,255,.8);
top: 7.5px;
left: 7.5px;
font-size: 12px;
font-weight: 900;
opacity: 1;
z-index: 2;
display: none;
cursor: pointer;
}
.findVersionButton:focus, .findVersionButton:hover, .findVersionButton:active,
.versionNextButton:focus, .versionNextButton:hover, .versionNextButton:active,
.versionPrevButton:focus, .versionPrevButton:hover, .versionPrevButton:active
{
background-color: rgba(50,50,50,1);
}
`);
}
if(mark_as_read_system_enabled)
{
addGlobalStyle(`
.readTag {
border-radius: 10px;
padding: 5px 10px;
position: absolute;
background-color: rgba(0,0,0,.7);
color: rgba(255,255,255,.8);
bottom: 7.5px;
right: 7.5px;
font-size: `+read_tag_font_size+`px;
font-weight: 900;
opacity: 1;
}
#markAsRead, #markAsRead:visited {
background-color: #3d9e48;
}
#markAsRead:active, #markAsRead:hover {
background-color: #52bc5e;
}
#markAsUnRead, #markAsUnRead:visited {
background-color: rgb(218, 53, 53);
}
#markAsUnRead:active, #markAsUnRead:hover {
background-color: #e26060;
}
.gallery {
position: relative;
}
`);
}
if(subscription_system_enabled) {
addGlobalStyle(`
#tags .subbedTag, #tags .subbedTag:visited {
background-color: #2c5030;
}
#tags .subbedTag:active, #tags .subbedTag:hover {
background-color: #416144;
}
#subTo, #subTo:visited {
background-color: #3d9e48;
}
#subTo:active, #subTo:hover {
background-color: #52bc5e;
}
#unsubTo, #unsubTo:visited {
background-color: rgb(218, 53, 53);
}
#unsubTo:active, #unsubTo:hover {
background-color: #e26060;
}
#sub-content ul {
text-align: left;
}
#sub-content li {
box-sizing: border-box;
display: inline-block;
width: 25%;
text-align: center;
padding: 5px 20px;
}
#subTo, #unsubTo {
height: auto;
line-height: initial;
cursor: pointer;
font-size: 0.5em;
padding: 6px 12px;
}
`);
}
}
//========================================================//
//================== On Comic info page ==================//
if(window.location.href.match(/^https:\/\/nhentai\.net\/g\/\d+?\/(\?.*|\#.*|)$/g)) //if on the comic info page
{
//=== Mark as read system ===//
if(mark_as_read_system_enabled) {
var item = window.location.href.split("nhentai.net")[1].split("?")[0].split("#")[0]; //get item from url
if(MARArray.includes(item)) //if item is marked as read
$(".buttons").append('<a href="#" id="markAsUnRead" class="btn btn-secondary">'+unreadImg+' <span style="vertical-align: middle;">Mark as unread</span></a>'); //..add unmark button
else
$(".buttons").append('<a href="#" id="markAsRead" class="btn btn-secondary">'+readImg+' <span style="vertical-align: middle;">Mark as read</span></a>'); //...add mark button
AddMARClickListeners();
}
//===========================//
//==== Subscribe system =====//
if(subscription_system_enabled) {
let SubArraySelector = SubArray.join("'], .tag[href='");
$(".tag[href='" + SubArraySelector + "']").addClass("subbedTag");
}
//===========================//
//=== HQ thumbnail system ===//
if(load_high_quality_pages_thumbnails && $("#thumbnail-container").length !== 0) {
$("#thumbnail-container .thumb-container > .gallerythumb > img").on("load", function(){
if($(this).attr("src").startsWith("http"))
{
$(this).attr("src", $(this).attr("data-src").replace(/\/\/t\d*?\./g, "//i.").replace("t.jpg", ".jpg").replace("t.png", ".png"));
//retry loading image
$(this).on("error", function(){
//count reload attempts
let attempts = parseInt($(this).attr("img-reloads"));
if(!attempts)
attempts = 0;
else if(attempts >= max_image_reload_attempts) //after x attempts, give up
{
$(this).off("error");
console.log("gave up on: " + $(this).attr("src"));
return;
}
$(this).attr("src", $(this).attr("src")); //reload
attempts++;
$(this).attr("img-reloads", attempts);
console.log("image reload attempt " + attempts + " for: " + $(this).attr("src"));
});
$(this).off("load");
}
});
}
//===========================//
}
//========================================================//
//============== On Artist/group info page ===============//
else if(subscription_system_enabled && (window.location.href.match(/^.+?\/artist\/.+?\/(popular)?(\?.*?|\#.*?|)$/g) || window.location.href.match(/^.+?\/group\/.+?\/(popular)?(\?.*?|\#.*?|)$/g))) //in artist or group page
{
var subItem = window.location.href.split("nhentai.net")[1].split("popular")[0].split("?")[0].split("#")[0]; //get item from url
if(SubArray.includes(subItem)) //if subscribed
$("h1").append('<a href="#" id="unsubTo" class="btn btn-secondary"><span style="vertical-align: middle;">Unsubscribe</span></a>'); //...add unsub button
else
$("h1").append('<a href="#" id="subTo" class="btn btn-secondary"><span style="vertical-align: middle;">Subscribe</span></a>'); //...add sub button
AddSubClickListeners();
}
//========================================================//
//====================== Subs page =======================//
else if(subscription_system_enabled && window.location.href.match(/^.+?\/subscriptions\/(\?.*|\#.*|)$/g)) //in subs page
{
$("head title").html('Subscriptions').prop("style", "font-size: 3.5em;");
$("#content").prepend('<h1>Subscriptions</h1>');
$("#content > .container").removeClass("error").addClass("artists-section").prop("id", "tag-container");
$(".artists-section").before("<h2 style='font-size: 2em;'>Artists</h2>");
$(".artists-section").after('<div class="container groups-section" id="tag-container"></div>');
$(".groups-section").before("<h2 style='font-size: 2em; margin-top: 50px;'>Groups</h2>");
var artistsHTML = "";
var groupsHTML = "";
for(let i = 0; i < SubArray.length; i++) {
if(SubArray[i].split("/")[1].split("/")[0] == "artist")
artistsHTML += '<a class="tag" href="'+SubArray[i]+'">'+(SubArray[i].split("/")[2].split("/")[0].replace(/\-/g, " "))+'</a>';
else
groupsHTML += '<a class="tag" href="'+SubArray[i]+'">'+(SubArray[i].split("/")[2].split("/")[0].replace(/\-/g, " "))+'</a>';
}
$(".artists-section").html(artistsHTML);
$(".groups-section").html(groupsHTML);
}
//========================================================//
//====================== Reader Page =====================//
else if(window.location.href.match(/^.+?\/g\/\d+?\/\d+\/$/g))
{
if(comic_reader_improved_zoom)
{
let prevVal = 1.0;
let curVal = prevVal;
SetReaderImageScale(curVal);
$('body').on('keydown', function(e) {
if(e.key == '+')
{
curVal = prevVal+0.1;
if(curVal > 3)
curVal = 3;
SetReaderImageScale(curVal);
prevVal = curVal;
}
else if(e.key == '-')
{
curVal = prevVal-0.1;
if(curVal < 0.1)
curVal = 0.1;
SetReaderImageScale(curVal);
prevVal = curVal;
}
});
$("section.reader-bar button.reader-zoom-out").click(function(e){
e.preventDefault();
e.stopPropagation();
curVal = prevVal-0.1;
if(curVal < 0.1)
curVal = 0.1;
SetReaderImageScale(curVal);
prevVal = curVal;
});
$("section.reader-bar button.reader-zoom-in").click(function(e){
e.preventDefault();
e.stopPropagation();
curVal = prevVal+0.1;
if(curVal > 3)
curVal = 3;
SetReaderImageScale(curVal);
prevVal = curVal;
});
}
}
//========================================================//
//====================== all pages with lists of comics ====================//
if($(".container.index-container, #favcontainer.container").length !== 0)
{
//=== Tag blocking system ===//
if(tag_blocking_enabled && BlockTagArray.length > 0)
{
let selector = "";
for(let i = 0; i < BlockTagArray.length; i++)
{
selector += ".gallery[data-tags*=" + BlockTagArray[i][0] + "]";
if(i < BlockTagArray.length-1)
selector += ", ";
}
$(selector).remove();
}
//===========================//
//=== HQ thumbnail system ===//
if(load_high_quality_browse_thumbnails) {
$(".container.index-container > .gallery > .cover > img, #favcontainer.container > .gallery-favorite > .gallery > .cover > img").on("load", function(){
if($(this).attr("src").startsWith("http"))
{
$(this).attr("src", $(this).attr("data-src").replace(/\/\/t\d*?\./g, "//i.").replace("thumb.jpg", "1.jpg").replace("thumb.png", "1.png"));
//console.log("image load for: " + $(this).attr("src"));
//retry loading image
$(this).on("error", function(){
//count reload attempts
let attempts = parseInt($(this).attr("img-reloads"));
if(!attempts)
attempts = 0;
else if(attempts >= max_image_reload_attempts) //after x attempts, give up
{
$(this).off("error");
console.log("gave up on: " + $(this).attr("src"));
return;
}
$(this).attr("src", $(this).attr("src")); //reload
attempts++;
$(this).attr("img-reloads", attempts);
console.log("image reload attempt " + attempts + " for: " + $(this).attr("src"));
});
$(this).off("load");
}
});
}
//===========================//
//=== Mark as read system ===//
if(mark_as_read_system_enabled) {
let MARArraySelector = MARArray.join("'], .cover[href='");
$(".cover[href='" + MARArraySelector + "']").append("<div class='readTag'>READ</div>");
}
//===========================//
//=== Version Grouping system ===//
if(version_grouping_enabled) {
$(".cover").parent().append("<div class='findVersionButton'>Find Alt Versions</div>");
$(".cover").parent().append("<div class='numOfVersions'>1/1</div>");
$(".cover").parent().append("<div class='versionNextButton'>►</div>");
$(".cover").parent().append("<div class='versionPrevButton'>◄</div>");
$(".findVersionButton").click(function(e){
e.preventDefault();
AddAltVersionsToThis($(this));
});
if(auto_group_on_page_comics && !remove_non_english)
GroupAltVersionsOnPage();
$(".versionPrevButton").click(function(e){
e.preventDefault();
let toHide = $(this).parent().find(".cover").filter(":visible");
let toShow = toHide.prev();
if(!toShow || toShow.length <= 0)
return;
if(!toShow.is(".cover"))
toShow = toHide.prevUntil(".cover", ":last").prev();
if(!toShow || toShow.length <= 0)
return;
toHide.hide(100);
toShow.show(100);
let n = $(this).parent().find(".numOfVersions");
n.text( (Number(n.text().split("/")[0])-1) + "/" + n.text().split("/")[1] );
});
$(".versionNextButton").click(function(e){
e.preventDefault();
let toHide = $(this).parent().find(".cover").filter(":visible");
let toShow = toHide.next();
if(!toShow || toShow.length <= 0)
return;
if(!toShow.is(".cover"))
toShow = toHide.nextUntil(".cover", ":last").next();
if(!toShow || toShow.length <= 0)
return;
toHide.hide(100);
toShow.show(100);
let n = $(this).parent().find(".numOfVersions");
n.text( (Number(n.text().split("/")[0])+1) + "/" + n.text().split("/")[1] );
});
}
//===========================//
}
//==========================================================================//
//====================== Settings page ===================//
else if($("#settings-container").length !== 0)
{
addGlobalStyle(`
#settings-container .custom-settings {
margin: 5px 5px 5px 20px;
}
#settings-container .custom-settings input[type="text"],
#settings-container .custom-settings input[type="number"]{
width: 70px;
height: 25px;
border-radius: 3px;
text-align: center;
padding: 0;
}
#settings-container .custom-settings.disabled-setting {
color: RGBA(153, 153, 153, 1);
opacity: 0.3;
}
#settings-container h2 {position: relative;}
#settings-container #settings-saved-mark {
color: green;
font-size: 15px;
position: absolute;
right: 0;
top: 10px;
display: none;
}
#importexportdiv {
position: fixed;
top: 10%;
left: 10%;
width: 80%;
height: 80%;
background-color: #393939;
padding: 3%;
border-radius: 15px;
}
#importexportdiv > textarea {
width: 100%;
height: 90%;
}
`);
let blockedTagsHTML = "";
for(let i = 0; i < BlockTagArray.length; i++)
blockedTagsHTML += "<a class='tag tag-"+BlockTagArray[i][0]+" href='#'><span class='name'>"+BlockTagArray[i][1]+"</span><span class='count'></span></a>";
let settingsHTML = `<br><div id="customSettingsContainer"><form class="form-horizontal" role="form">
<h2>NHentai Improved Settings <span id="settings-saved-mark">Saved 🗸</span></h2>
<h3>Non-English Settings</h3>
<div class="custom-settings"><div class="form-control">
<label><input id="remove_non_english" type="checkbox">
Remove Non-English</label>
</div></div>
<div class="custom-settings"><div class="form-control">
<label><input id="partially_fade_all_non_english" type="checkbox">
Partially Fade Non-English</label>
</div></div>
<div class="custom-settings">
<label>Non-English Fade Opacity
<input id="non_english_fade_opacity" type="text" placeholder="0.0 - 1.0" autocomplete="off"></label>
</div>
<h3>Browse Section Settings</h3>
<div class="custom-settings" title="height scales automatically">
<label>Thumbnail Width
<input id="browse_thumbnail_width" type="number" placeholder="250"> px</label>
</div>
<div class="custom-settings" title="max-width = 100% of available space, meaning no need to worry about going too big">
<label>Thumbnail Container Width
<input id="browse_thumnail_container_width" type="number" placeholder="1350"> px</label>
</div>
<div class="custom-settings"><div class="form-control">
<label><input id="load_high_quality_browse_thumbnails" type="checkbox">
HQ Thumbnails</label>
</div></div>
<h3>Comic Pages Section Settings</h3>
<div class="custom-settings" title="height scales automatically">
<label>Thumbnail Width
<input id="pages_thumbnail_width" type="number" placeholder="250"> px</label>
</div>
<div class="custom-settings" title="max-width = 100% of available space, meaning no need to worry about going too big">
<label>Thumbnail Container Width
<input id="pages_thumnail_container_width" type="number" placeholder="1350"> px</label>
</div>
<div class="custom-settings"><div class="form-control">
<label><input id="load_high_quality_pages_thumbnails" type="checkbox">
HQ Thumbnails</label>
</div></div>
<h3>Comic Reader Settings</h3>
<div class="custom-settings"><div class="form-control">
<label><input id="comic_reader_improved_zoom" type="checkbox">
Improved Zoom</label>
</div></div>
<h3>Mark As Read Settings</h3>
<div class="custom-settings"><div class="form-control">
<label><input id="mark_as_read_system_enabled" type="checkbox">
Enabled</label>
</div></div>
<div class="custom-settings">
<label>Fade Opacity
<input id="marked_as_read_fade_opacity" type="text" placeholder="0.0 - 1.0" autocomplete="off"></label>
</div>
<div class="custom-settings">
<label>Read Tag Font Size
<input id="read_tag_font_size" type="number" placeholder="15"> px</label>
</div>
<h3>Subscription Settings</h3>
<div class="custom-settings"><div class="form-control">
<label><input id="subscription_system_enabled" type="checkbox">
Enabled</label>
</div></div>
<h3>Version Grouping Settings</h3>
<div class="custom-settings"><div class="form-control">
<label><input id="version_grouping_enabled" type="checkbox">
Enabled</label>
</div></div>
<div class="custom-settings"><div class="form-control">
<label><input id="version_grouping_filter_brackets" type="checkbox">
Filter out normal brackets for version searches<br><sup>(square brackets are always filtered out regardless of this setting)</sup></label>
</div></div>
<div class="custom-settings"><div class="form-control">
<label><input id="auto_group_on_page_comics" type="checkbox">
Automatically group on-page comics<br><sup>(doesn't search the site, just current page)</sup><br><sup style="top: -1em;">(Currently does not properly work with "Remove Non-English")</sup></label>
</div></div>
<h3>Tag Blocking Settings</h3>
<div class="custom-settings"><div class="form-control">
<label><input id="tag_blocking_enabled" type="checkbox">
Enabled</label>
</div></div>
<p>Currently Blocked Tags:</p>
`+(BlockTagArray.length > 0 ? `
<span class="tags">`+blockedTagsHTML+`</span>
` : "none")+`
<br><br>
</form>
<div style="max-width: 800px; margin-left: auto; margin-right: auto;"><button id="importexportButt">Import/Export Subs and Marked as Read</button></div>
<br><br>
</div>`;
$("#settings-container").append(settingsHTML);
InitialValuesForSettings();
$("#settings-container form:last").change(function(){
UpdateSettingsValues();
});
$("#importexportButt").click(function(){
if($("#importexportdiv").length == 0)
{
$("html").append(`<div id="importexportdiv"><textarea></textarea><br><br><button id="saveimportexport">Import</button><button id="backimportexport">Back</button></div>`);
$("#importexportdiv > textarea").val(SubArrayString + "|||||" + MARArrayString);
$("#saveimportexport").click(function(){
if($("#importexportdiv > textarea").val().indexOf("|||||") < 0) {
alert("invalid data");
return;
}
SubArrayString = $("#importexportdiv > textarea").val().split("|||||")[0];
MARArrayString = $("#importexportdiv > textarea").val().split("|||||")[1];
GM_setValue("SubArrayString", SubArrayString);
GM_setValue("MARArrayString", MARArrayString);
alert("Done!");
location.reload();
});
$("#backimportexport").click(function(){
$("#importexportdiv").remove();
});
}
});
}
//========================================================//
//====================== All pages =======================//
if(subscription_system_enabled) {
$(".menu.right").prepend('<li><a href="/subscriptions/"><i class="fa fa-heartbeat"></i> Subscriptions</a></li>');
}
if(tag_blocking_enabled)
{
if($("a.tag > .count").length > 0)
{
$("a.tag > .count").each(function(){
//console.log($(this).css("background-color"));
$(this).append(`<div class="blockTagButton" alt="block-tag" title="` +
($(this).css("background-color") == "rgb(85, 0, 0)" ||
$(this).css("background-color") == "rgb(85,0,0)" ||
$(this).css("background-color") == "#500" ||
$(this).css("background-color") == "#550000"
? `un` : ``)+`block tag">`+banIcon+`</div>`);
});
$(".blockTagButton").click(function(e){
e.preventDefault();
e.stopPropagation();
ToggleTagFromBlockArray($(this).parent().parent().attr("class").split("tag-")[1].split(" ")[0], $(this).parent().parent().find(".name").text().trim()); //$(this).parent().clone().children().remove().end().text().trim()
});
}
}
//========================================================//
function SetReaderImageScale(scale)
{
$("section.reader-bar .zoom-level > .value").html(scale.toFixed(1));
$("#image-container img").css("width", 1280 * scale);
}
function ToggleTagFromBlockArray(tag, tagname)
{
//get the array again to make sure we have an up to date array (since other tabs could have modified it since loading this page)
BlockTagArrayString = GM_getValue("BlockTagArrayString", null);
if(BlockTagArrayString) { BlockTagArray = JSON.parse(BlockTagArrayString); }
//console.log("operating on: " + tag + " - " + tagname);
let tagObj = [tag, tagname];
let tagObjString = JSON.stringify(tagObj);
if(BlockTagArrayString.indexOf(tagObjString) >= 0) //remove from blocked
{
//console.log(BlockTagArrayString);
BlockTagArrayString = BlockTagArrayString.replace(tagObjString+",", "").replace(","+tagObjString, "").replace(tagObjString, "");
//console.log(BlockTagArrayString);
BlockTagArray = JSON.parse(BlockTagArrayString);
if($("#settings-container").length !== 0) //if on settings page, remove the tag from the list when unblocking
$("a.tag.tag-"+tag).remove();
else
{
$("a.tag.tag-"+tag+" .blockTagButton").attr("title", "block tag");
$("a.tag.tag-"+tag+" > .name").css("background-color", "#4d4d4d");
$("a.tag.tag-"+tag+" > .count").css("background-color", "#333");
$("a.tag.tag-"+tag).hover(function(){
$("a.tag.tag-"+tag+" > .name").css("background-color", "#595959");
$("a.tag.tag-"+tag+" > .count").css("background-color", "#404040");
}, function(){
$("a.tag.tag-"+tag+" > .name").css("background-color", "#4d4d4d");
$("a.tag.tag-"+tag+" > .count").css("background-color", "#333");
});
}
}
else //add to blocked
{
BlockTagArray.push(tagObj);
$("a.tag.tag-"+tag+" .blockTagButton").attr("title", "unblock tag");
$("a.tag.tag-"+tag+" > .name, a.tag.tag-"+tag+" > .count").css("background-color", "#500");
$("a.tag.tag-"+tag).off();
}
BlockTagArrayString = JSON.stringify(BlockTagArray); //covert array to string
GM_setValue("BlockTagArrayString", BlockTagArrayString); //save string
}
function GroupAltVersionsOnPage()
{
let i = 0;
let found = $(".container > .gallery");
while(!!found && i < found.length)
{
AddAltVersionsToThisFromPage(found[i]);
i++;
found = $(".container > .gallery");
}
}
function AddAltVersionsToThisFromPage(target)
{
let place = $(target);
place.addClass("ignoreThis");
let title = place.find(".cover > .caption").text();
if(!title || title.length <= 0)
return;
let found = $(".container > .gallery:not(.ignoreThis)");
let numOfValid = 0;
for(let i = 0; i < found.length; i++) //loop through galleries
{
let cap = $(found[i]).find(".caption");
if(cap.length == 1) //if the gallery includes just one item
{
if(IncludesAll(cap.text(), title)) //valid target
{
if(partially_fade_all_non_english)
$(found[i]).find(".cover > img, .cover > .caption").css("opacity", non_english_fade_opacity);
if($(found[i]).attr("data-tags").includes("12227")) //en
{
$(found[i]).find(".caption").append(`<img class="overlayFlag" src="`+flagEn+`">`);
$(found[i]).find(".cover > img, .cover > .caption").css("opacity", "1");
}
else
{
if($(found[i]).attr("data-tags").includes("6346")) //jp
$(found[i]).find(".caption").append(`<img class="overlayFlag" src="`+flagJp+`">`);
else if($(found[i]).attr("data-tags").includes("29963")) //ch
$(found[i]).find(".caption").append(`<img class="overlayFlag" src="`+flagCh+`">`);
if(!partially_fade_all_non_english)
$(found[i]).find(".cover > img, .cover > .caption").css("opacity", "1");
}
if(mark_as_read_system_enabled) {
let MARArraySelector = MARArray.join("'], .cover[href='");
$(found[i]).find(".cover[href='" + MARArraySelector + "']").append("<div class='readTag'>READ</div>");
let readTag = $(found[i]).find(".readTag");
if(!!readTag && readTag.length > 0)
readTag.parent().parent().find(".cover > img, .cover > .caption").css("opacity", marked_as_read_fade_opacity);
}
place.append($(found[i]).find(".cover"));
$(found[i]).addClass("deleteThis");
numOfValid++;
}
}
else //the gallery incvludes multiple items
{
let addThese = false;
for(let j = 0; j < cap.length; j++) //loop through items in the gallery
{
if(IncludesAll($(cap[j]).text(), title))
{
addThese = true; //if any of them match
break;
}
}
if(addThese) //if any matched
{
for(let j = 0; j < cap.length; j++)
place.append($(cap[j]).parent()); //add all
$(found[i]).addClass("deleteThis");
numOfValid += cap.length;
}
}
}
numOfValid++;
place.removeClass("deleteThis");
place.removeClass("ignoreThis");
$(".deleteThis").remove();
if(numOfValid > 1)
{
place.find(".cover:not(:first)").css("display", "none");
place.find(".versionPrevButton, .versionNextButton, .numOfVersions").show(200);
place.find(".numOfVersions").text("1/" + numOfValid);
//place.find(".findVersionButton").hide();
}
}
function IncludesAll(string, search)
{
string = CleanupSearchString(string);
search = CleanupSearchString(search);
let yes = true;
let searches = search.split(" ");
//console.log(string + " ::: includes all::: " + searches);
for(let i = 0; i < searches.length; i++)
if(!!searches[i] && searches[i].length > 0 && !string.includes(searches[i]))
yes = false;
//console.log(yes);
return yes;
}
function AddAltVersionsToThis(target)
{
let place = target;
let title = place.parent().find(".cover:visible > .caption").text();
$.get(BuildUrl(title), function(data){
let found = $(data).find(".container > .gallery");
if(!found || found.length <= 0)
{
alert("error reading data");
return;
}
place.parent().find(".cover").remove();
try
{
for(let i = 0; i < found.length; i++)
{
if(partially_fade_all_non_english)
$(found[i]).find(".cover > img, .cover > .caption").css("opacity", non_english_fade_opacity);
if($(found[i]).attr("data-tags").includes("12227")) //en
{
$(found[i]).find(".caption").append(`<img class="overlayFlag" src="`+flagEn+`">`);
$(found[i]).find(".cover > img, .cover > .caption").css("opacity", "1");
}
else
{
if($(found[i]).attr("data-tags").includes("6346")) //jp
$(found[i]).find(".caption").append(`<img class="overlayFlag" src="`+flagJp+`">`);
else if($(found[i]).attr("data-tags").includes("29963")) //ch
$(found[i]).find(".caption").append(`<img class="overlayFlag" src="`+flagCh+`">`);
if(!partially_fade_all_non_english)
$(found[i]).find(".cover > img, .cover > .caption").css("opacity", "1");
}
if(mark_as_read_system_enabled) {
let MARArraySelector = MARArray.join("'], .cover[href='");
$(found[i]).find(".cover[href='" + MARArraySelector + "']").append("<div class='readTag'>READ</div>");
let readTag = $(found[i]).find(".readTag");
if(!!readTag && readTag.length > 0)
readTag.parent().parent().find(".cover > img, .cover > .caption").css("opacity", marked_as_read_fade_opacity);
}
let thumbnailReplacement;
if(!!$(found[i]).find(".cover > img").attr("data-src"))
thumbnailReplacement = $(found[i]).find(".cover > img").attr("data-src").replace("//t.", "//i.").replace("thumb.jpg", "1.jpg").replace("thumb.png", "1.png");
else
thumbnailReplacement = $(found[i]).find(".cover > img").attr("src").replace("//t.", "//i.").replace("thumb.jpg", "1.jpg").replace("thumb.png", "1.png");
$(found[i]).find(".cover > img").attr("src", thumbnailReplacement);
place.parent().append($(found[i]).find(".cover"));
}
}
catch(er)
{
alert("error modifying data: " + er);
return;
}
place.parent().find(".cover:not(:first)").css("display", "none");
place.parent().find(".versionPrevButton, .versionNextButton, .numOfVersions").show(200);
place.parent().find(".numOfVersions").text("1/" + (found.length));
place.hide(200);
}).fail(function(e){
alert("error getting data: " + e);
});
}
function CleanupSearchString(title)
{
title = title.replace(/\[.*?\]/g, "");
title = title.replace(/\【.*?\】/g, "");
if(version_grouping_filter_brackets)
title = title.replace(/\(.*?\)/g, "");
return title;
}
function BuildUrl(title)
{
let url = CleanupSearchString(title);
url = url.replace(/\s+?-/g, " ");
url = url.replace(/\s\S+?:\S.*?\s/g, " "); //remove two part words with ":" in the middle e.g. "Re:Dive", because the site search can't handle that and just removing the ":" breaks the word again ruining the search
url = url.replace(/[,|♡|♂|♀|;|:|…]/g, " "); //some symbols do not get handled by encodeURIComponent and break search.
//Currently not sure how to go about creating a whitelist because of all the japanese/chinese etc. so I guess I'll just filter out some specific problem symbols as I run into them
//though "," is filtered out for another reason, mainly because it's used so inconsistently in titles
url = url.trim();
url = encodeURIComponent(url);
//alert(url);
url = "https://nhentai.net/search/?q=" + url;
return url;
}
function InitialValuesForSettings() {
$("#remove_non_english").prop("checked", remove_non_english);
$("#partially_fade_all_non_english").prop("checked", partially_fade_all_non_english);
$("#non_english_fade_opacity").val(non_english_fade_opacity);
$("#browse_thumbnail_width").val(browse_thumbnail_width);
$("#browse_thumnail_container_width").val(browse_thumnail_container_width);
$("#load_high_quality_browse_thumbnails").prop("checked", load_high_quality_browse_thumbnails);
$("#pages_thumbnail_width").val(pages_thumbnail_width);
$("#pages_thumnail_container_width").val(pages_thumnail_container_width);
$("#load_high_quality_pages_thumbnails").prop("checked", load_high_quality_pages_thumbnails);
$("#mark_as_read_system_enabled").prop("checked", mark_as_read_system_enabled);
$("#marked_as_read_fade_opacity").val(marked_as_read_fade_opacity);
$("#read_tag_font_size").val(read_tag_font_size);
$("#subscription_system_enabled").prop("checked", subscription_system_enabled);
$("#version_grouping_enabled").prop("checked", version_grouping_enabled);
$("#version_grouping_filter_brackets").prop("checked", version_grouping_filter_brackets);
$("#auto_group_on_page_comics").prop("checked", auto_group_on_page_comics);
$("#tag_blocking_enabled").prop("checked", tag_blocking_enabled);
$("#comic_reader_improved_zoom").prop("checked", comic_reader_improved_zoom);
DisableEnableSettingsByValue();
}
function UpdateSettingsValues() {
remove_non_english = $("#remove_non_english").is(':checked');
partially_fade_all_non_english = $("#partially_fade_all_non_english").is(':checked');
non_english_fade_opacity = $("#non_english_fade_opacity").val();
browse_thumbnail_width = $("#browse_thumbnail_width").val();
browse_thumnail_container_width = $("#browse_thumnail_container_width").val();
load_high_quality_browse_thumbnails = $("#load_high_quality_browse_thumbnails").is(':checked');
pages_thumbnail_width = $("#pages_thumbnail_width").val();
pages_thumnail_container_width = $("#pages_thumnail_container_width").val();
load_high_quality_pages_thumbnails = $("#load_high_quality_pages_thumbnails").is(':checked');
mark_as_read_system_enabled = $("#mark_as_read_system_enabled").is(':checked');
marked_as_read_fade_opacity = $("#marked_as_read_fade_opacity").val();
read_tag_font_size = $("#read_tag_font_size").val();
subscription_system_enabled = $("#subscription_system_enabled").is(':checked');
version_grouping_enabled = $("#version_grouping_enabled").is(':checked');
version_grouping_filter_brackets = $("#version_grouping_filter_brackets").is(':checked');
auto_group_on_page_comics = $("#auto_group_on_page_comics").is(':checked');
tag_blocking_enabled = $("#tag_blocking_enabled").is(':checked');
comic_reader_improved_zoom = $("#comic_reader_improved_zoom").is(':checked');
GM_setValue("remove_non_english", remove_non_english);
GM_setValue("partially_fade_all_non_english", partially_fade_all_non_english);
GM_setValue("non_english_fade_opacity", non_english_fade_opacity);
GM_setValue("browse_thumbnail_width", browse_thumbnail_width);
GM_setValue("browse_thumnail_container_width", browse_thumnail_container_width);
GM_setValue("load_high_quality_browse_thumbnails", load_high_quality_browse_thumbnails);
GM_setValue("pages_thumbnail_width", pages_thumbnail_width);
GM_setValue("pages_thumnail_container_width", pages_thumnail_container_width);
GM_setValue("load_high_quality_pages_thumbnails", load_high_quality_pages_thumbnails);
GM_setValue("mark_as_read_system_enabled", mark_as_read_system_enabled);
GM_setValue("marked_as_read_fade_opacity", marked_as_read_fade_opacity);
GM_setValue("read_tag_font_size", read_tag_font_size);
GM_setValue("subscription_system_enabled", subscription_system_enabled);
GM_setValue("version_grouping_enabled", version_grouping_enabled);
GM_setValue("version_grouping_filter_brackets", version_grouping_filter_brackets);
GM_setValue("auto_group_on_page_comics", auto_group_on_page_comics);
GM_setValue("tag_blocking_enabled", tag_blocking_enabled);
GM_setValue("comic_reader_improved_zoom", comic_reader_improved_zoom);
$("#settings-saved-mark").fadeIn(500, function() {
setTimeout(function() {
$("#settings-saved-mark").fadeOut(500);
}, 1000);
});
DisableEnableSettingsByValue();
}
function DisableEnableSettingsByValue()
{
if(remove_non_english) {
$("#partially_fade_all_non_english").prop("disabled", true);
$("#non_english_fade_opacity").prop("disabled", true);
$("#partially_fade_all_non_english").parentsUntil(".custom-settings").parent().addClass("disabled-setting");
$("#non_english_fade_opacity").parentsUntil(".custom-settings").parent().addClass("disabled-setting");
}
else {
$("#partially_fade_all_non_english").prop("disabled", false);
$("#non_english_fade_opacity").prop("disabled", false);
$("#partially_fade_all_non_english").parentsUntil(".custom-settings").parent().removeClass("disabled-setting");
$("#non_english_fade_opacity").parentsUntil(".custom-settings").parent().removeClass("disabled-setting");
$("#auto_group_on_page_comics").prop("disabled", false);
$("#auto_group_on_page_comics").parentsUntil(".custom-settings").parent().removeClass("disabled-setting");
if(!partially_fade_all_non_english) {
$("#non_english_fade_opacity").prop("disabled", true);
$("#non_english_fade_opacity").parentsUntil(".custom-settings").parent().addClass("disabled-setting");
}
else {
$("#non_english_fade_opacity").prop("disabled", false);
$("#non_english_fade_opacity").parentsUntil(".custom-settings").parent().removeClass("disabled-setting");
}
}
if(mark_as_read_system_enabled) {
$("#marked_as_read_fade_opacity, #read_tag_font_size").prop("disabled", false);
$("#marked_as_read_fade_opacity, #read_tag_font_size").parentsUntil(".custom-settings").parent().removeClass("disabled-setting");
}
else {
$("#marked_as_read_fade_opacity, #read_tag_font_size").prop("disabled", true);
$("#marked_as_read_fade_opacity, #read_tag_font_size").parentsUntil(".custom-settings").parent().addClass("disabled-setting");
}
if(version_grouping_enabled) {
$("#version_grouping_filter_brackets").prop("disabled", false);
$("#version_grouping_filter_brackets").parentsUntil(".custom-settings").parent().removeClass("disabled-setting");
if(remove_non_english)
{
$("#auto_group_on_page_comics").prop("disabled", true);
$("#auto_group_on_page_comics").parentsUntil(".custom-settings").parent().addClass("disabled-setting");
}
else
{
$("#auto_group_on_page_comics").prop("disabled", false);
$("#auto_group_on_page_comics").parentsUntil(".custom-settings").parent().removeClass("disabled-setting");
}
}
else {
$("#version_grouping_filter_brackets").prop("disabled", true);
$("#version_grouping_filter_brackets").parentsUntil(".custom-settings").parent().addClass("disabled-setting");
$("#auto_group_on_page_comics").prop("disabled", true);
$("#auto_group_on_page_comics").parentsUntil(".custom-settings").parent().addClass("disabled-setting");
}
}
function AddSubClickListeners() {
$("#subTo").click(function(){
//get the array again to make sure we have an up to date array (since other tabs could have modified it since loading this page)
SubArrayString = GM_getValue("SubArrayString", null);
if(SubArrayString) { SubArray = JSON.parse(SubArrayString); }
SubArray.push(subItem); //add to array
SubArrayString = JSON.stringify(SubArray); //convert array to string
GM_setValue("SubArrayString", SubArrayString); //save string
$(this).html('<span style="vertical-align: middle;">Unsubscribe</span>').prop("id", "unsubTo");
$(this).off();
AddSubClickListeners();
});
$("#unsubTo").click(function(){
//get the array again to make sure we have an up to date array (since other tabs could have modified it since loading this page)
SubArrayString = GM_getValue("SubArrayString", null);
if(SubArrayString) { SubArray = JSON.parse(SubArrayString); }
//do it mutiple times if needed (due to multiple tab fuckery)
while(SubArray.indexOf(subItem) >= 0)
SubArray.splice(SubArray.indexOf(subItem), 1); //remove from array
SubArrayString = JSON.stringify(SubArray); //convert array to string
GM_setValue("SubArrayString", SubArrayString); //save string
$(this).html('<span style="vertical-align: middle;">Subscribe</span>').prop("id", "subTo");
$(this).off();
AddSubClickListeners();
});
}
function AddMARClickListeners() {
$("#markAsRead").click(function(){
//get the array again to make sure we have an up to date array (since other tabs could have modified it since loading this page)
MARArrayString = GM_getValue("MARArrayString", null);
if(MARArrayString) { MARArray = JSON.parse(MARArrayString); }
MARArray.push(item); //add to array
MARArrayString = JSON.stringify(MARArray); //covert array to string
GM_setValue("MARArrayString", MARArrayString); //save string
$(this).html(unreadImg+' <span style="vertical-align: middle;">Mark as unread</span>').prop("id", "markAsUnRead");
$(this).off();
AddMARClickListeners();
});
$("#markAsUnRead").click(function(){
//get the array again to make sure we have an up to date array (since other tabs could have modified it since loading this page)
MARArrayString = GM_getValue("MARArrayString", null);
if(MARArrayString) { MARArray = JSON.parse(MARArrayString); }
//do it mutiple times if needed (due to multiple tab fuckery)
while(MARArray.indexOf(item) >= 0)
MARArray.splice(MARArray.indexOf(item), 1); //remove from array
MARArrayString = JSON.stringify(MARArray); //covert array to string
GM_setValue("MARArrayString", MARArrayString); //save string
$(this).html(readImg+' <span style="vertical-align: middle;">Mark as read</span>').prop("id", "markAsRead");
$(this).off();
AddMARClickListeners();
});
}
function addGlobalStyle(css) {
var head, style;
head = document.getElementsByTagName('head')[0];
if (!head) { return; }
style = document.createElement('style');
style.type = 'text/css';
style.innerHTML = css;
head.appendChild(style);
}
})();