您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Links between E-Hentai and ExHentai page, and also links user to ExHentai automatically if gallery is "removed" and adds "view later" function
// ==UserScript== // @name E(X)Hentai Helper // @description Links between E-Hentai and ExHentai page, and also links user to ExHentai automatically if gallery is "removed" and adds "view later" function // @namespace https://greasyfork.org/en/scripts/24342-e-hentai-exhentai // @version 4.05 // @icon https://e-hentai.org/favicon.ico // @resource exCSS http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css // @resource jqueryui https://code.jquery.com/ui/1.12.0/jquery-ui.min.js // @include https://upload.e-hentai.org/* // @include http*://e-hentai.org/* // @include http*://exhentai.org/* // @exclude https://e-hentai.org/archive* // @exclude https://e-hentai.org/gallery* // @exclude https://exhentai.org/archive* // @exclude https://exhentai.org/gallery* // @require https://code.jquery.com/jquery-3.1.1.min.js // @require https://code.jquery.com/ui/1.12.1/jquery-ui.min.js // @require https://cdn.jsdelivr.net/npm/[email protected]/js/jquery.dataTables.js // @require https://greasyfork.org/scripts/27104-filesaver/code/FileSaver.js?version=173518 // @author Resuha // @grant GM_addStyle // @grant GM_getValue // @grant GM_setValue // @grant GM_getResourceText // ==/UserScript== //Credit to developer of https://github.com/js-cookie/js-cookie //Ver 4.00 changed "view/read later" layout //Ver 3.00 added "view/read later" functionality //Ver 2.00 added redirector and cookie remover var targetWebsite = ""; var theme = ""; var readLaterList = []; var lastHovered; var currentPageLink = window.location.href; var dataTable; var cssTxt = GM_getResourceText("exCSS"); GM_addStyle(cssTxt); var jqueryui = GM_getResourceText("jqueryui"); GM_addStyle(jqueryui); var extraCSS = document.createElement("style"); extraCSS.textContent = ` .link, .option { cursor: pointer; text-decoration: underline; } .option, #placeholderText{font-size: 125%} .readLaterItem{font-size: 125%} .readLaterItem > .option{font-size: 100%} .divHeader{ font-size: 160%; font-weight: bold; } #fixedDiv.dark, #readLaterDiv.dark,#successDiv.dark,#previewDiv.dark,#addDiv.dark{ background-color:rgba(64, 64, 0, 1); border: 1px solid rgba(255, 255, 0, 1); } .link.dark{color:yellow} .option.dark{color:plum} #mpvAddon.dark{background-color:rgba(64, 64, 0, 0.4)} #fixedDiv.light, #readLaterDiv.light,#successDiv.light,#previewDiv.light,#addDiv.light{ background-color:rgba(255, 255, 0, 1); border: 1px solid rgba(64, 64, 0, 1); } .link.light{color:blue} .option.light{color:Red} #mpvAddon.light{background-color:rgba(255, 255, 0, 0.4)} #successDiv{ font-size: 125%; position: absolute; transform: translate(-100%, -50%); z-index:10; padding: 8px 8px; } #linker{font-size: 160%} #fixedDiv{ text-align: left !important; position: fixed; top: 12px; right: 12px; align: left; padding: 8px 8px; z-index:10; } #fixedDivPeek{ text-align: left !important; position: fixed; top: 0px; right: 0px; width: 10px; height: 10px; background-color:rgba(255, 255, 0, 1); align: left; padding: 8px 8px; z-index:10; } #readLaterDiv{ text-align: left !important; position:fixed; bottom: 4%;left: 2%; align: left; z-index:10; padding: 8px 8px; } #i1 > #mpvAddon{ float:right; padding:0px 10px 10px 10px; cursor: pointer; } #optionDivUL, #readLaterOptionDivUL{ margin: 0; padding: 0px 0px 0px 20px; } .topRightDivButton{ float:right; cursor: pointer; padding: 0px 4px 2px 3px; border: 1px solid; font-size: 80%; } #previewDiv{ position:fixed; z-index:10; padding:4px; } #previewDiv.showLeft{transform: translate(-110%, -105%)} #previewDiv.showRight{transform: translate(10%, -105%)} #addDiv{ position:absolute; z-index:10; padding:4px; font-size:125%; cursor: pointer; } .readLaterItem.hoverPopup.odd.light{background:rgba(240, 240, 0, 1)} .readLaterItem.hoverPopup.odd.dark{background:rgba(48, 48, 0, 1)} #readLaterTable.light{border:2px rgba(64, 64, 0, 1) solid} #readLaterTable.dark{border:2px rgba(255, 255, 0, 1) solid} .highlighted{font-weight: bold !important;} .highlighted.light{color: red} .highlighted.dark{color: lightblue} `; document.head.appendChild(extraCSS); var fixedDiv = `' <div id="fixedDiv"> <div class="divHeader"><label id="scriptTitleHeader">E(X)Hentai Helper v`+ GM_info.script.version + `</label><label class="topRightDivButton" id="minmaxFixedDivButton">–</label></div><BR> <div id="linkerDiv"> <label class="divHeader">Linker:</label> </div> <div id="readLaterOptionDiv"><BR> <label class="divHeader">Read Later:</label><BR><ul id="readLaterOptionDivUL"></ul> </div> <div id="optionDiv"><BR> <label class="divHeader">Option:</label><BR><ul id="optionDivUL"></ul> </div> </div>'`; $('body').append(fixedDiv); fixedDiv = $('#fixedDiv'); linkerDiv = $('#linkerDiv'); optionDiv = $('#optionDiv'); optionDiv.hide(); document.getElementById('minmaxFixedDivButton').addEventListener("click", function () { if ($('#scriptTitleHeader').is(":visible")) { hideFixedDivContent(); } else { showFixedDivContent(); } }); var readLaterDiv = `' <div id="readLaterDiv" style="width:96%"> <div class="divHeader"><label id="rlDivHeader">Read Later List:</label><label class="topRightDivButton" id="closeReadLaterButton">✖</label></div> <div id="readLaterTableWrapper"></div> </div>'`; $('body').append(readLaterDiv); document.getElementById('closeReadLaterButton').addEventListener("click", function () { hide_rlList(); }); readLaterDiv = $('#readLaterDiv'); readLaterDiv.hide(); var previewDiv = `' <div id="previewDiv"> <img id="previewImg" src=""></img><label id="placeholderText"></label> </div>'`; $('body').append(previewDiv); document.getElementById('closeReadLaterButton').addEventListener("click", function () { hide_rlList(); }); previewDiv = $('#previewDiv'); previewDiv.hide(); var addDiv = '<div id="addDiv"><label id="addDivLabel">Add to "view later" list</label></div>'; $('body').append(addDiv); addDiv = $('#addDiv'); addDiv.hide(); $("#addDiv").click(function () { var title = lastHovered.getElementsByClassName("id2")[0].childNodes[0].innerHTML; var link = parse_gallery_identifier(lastHovered.getElementsByClassName("id2")[0].childNodes[0].href); var thumbnailLink = lastHovered.getElementsByClassName("id3")[0].childNodes[0].childNodes[0].src.replace("exhentai.org", "ehgt.org"); if (thumbnailLink.indexOf("blank.gif") > -1) { //if there is no thumbnail, do AJAX call $(document).ajaxComplete(function (event, xhr, settings) { var data = xhr.responseText; var divStyle = $("#gd1", data).children('div').attr("style").split(" "); if (divStyle[3].startsWith("url")) { thumbnailLink = divStyle[3].substring(divStyle[3].indexOf("(") + 1, divStyle[3].indexOf(")")); } else { for (i = 0; i < stuff.length; i++) { if (divStyle[i].startsWith("url")) { thumbnailLink = divStyle[i].substring(divStyle[i].indexOf("(") + 1, divStyle[i].indexOf(")")); break; } } } thumbnailLink = thumbnailLink.replace("exhentai.org", "ehgt.org"); add_rlEntry(title, link, thumbnailLink); populate_rlDiv(); }); $.ajax(link); } else { add_rlEntry(title, link, thumbnailLink); populate_rlDiv(); } }); if (document.location.href.indexOf('exhentai') !== - 1) { link = 'https://e-hentai.org' + parse_gallery_identifier(); targetWebsite = 'E-Hentai'; theme = "dark"; } else { link = 'https://exhentai.org' + parse_gallery_identifier(); targetWebsite = 'ExHentai'; theme = "light"; } // Determine if the current page is E-Hentai or ExHentai readLaterDiv.resizable({ handles: "n,e,ne", stop: function (event, ui) { $('th')[0].click(); } }); fixedDiv.addClass("light"); readLaterDiv.addClass("light"); previewDiv.addClass("light"); addDiv.addClass("light"); $('#readLaterTable').addClass("light"); redoTheme(); window.addEventListener('focus', populate_rlDiv); $(document).ready(function () { populate_rlDiv(); if (document.title == 'Gallery Not Available - E-Hentai Galleries') { // Gallery is expunged in e-hentai document.location.href = 'https://exhentai.org' + parse_gallery_identifier(); } else if (document.title == "exhentai.org (260×260)") { // Got sadpanda var bYes = '<button id="yesButton" class="askButton">Yes'; var bNo = '<button id="noButton" class="askButton">No'; var askConfirm = '<div id="confirmDiv">Are you currently logged in at e-hentai.org forum?<label id="message"><br>' + bYes + bNo + '</div>'; $('body').append(askConfirm); askConfirm = $('#confirmDiv'); askConfirm.css({ 'align': 'center', 'color': 'blue', }); $('#yesButton').click(function () { // Clear cookie and refresh $('#confirmDiv').text("This page will refresh. If you still see this page after the refresh, it is possible that your account is not old enough for exhentai"); setTimeout(function () { // delete cookie Cookies.remove('yay', { domain: '.exhentai.org' }); location.reload(); }, 1000); }); $('#noButton').click(function () { // Redirect to forum $('#confirmDiv').text("Redirecting to E-Hentai login page"); setTimeout(function () { document.location.href = 'https://forums.e-hentai.org/index.php?act=Login&CODE=00'; }, 1000); }); } else { if (currentPageLink.indexOf("/mpv/") === -1) { $(".id1").hover(function () { lastHovered = this; var location = getOffset(this.getElementsByClassName("id3")[0]); addDiv.show(); addDiv.css({ "top": location.top + "px", "left": location.left + "px", }); if (getIndex_rlList(parse_gallery_identifier(lastHovered.getElementsByClassName("id3")[0].childNodes[0].href)).exactMatch) { $("#addDivLabel").text('Already added to list'); } }, function () { addDiv.hide(); $("#addDivLabel").text('Add to "view later" list'); }); addDiv.hover(function () { addDiv.show(); if (getIndex_rlList(parse_gallery_identifier(lastHovered.getElementsByClassName("id3")[0].childNodes[0].href)).exactMatch) { $("#addDivLabel").text('Already added to list'); } else { $("#addDiv").css("color", "red"); } }, function () { $("#addDiv").hide(); $("#addDiv").css("color", ""); }); var link; var linker; if (targetWebsite == 'ExHentai') { if (document.location.href == 'https://upload.e-hentai.org/manage.php') { linker = "https://exhentai.org/upload/manage.php"; } else { linker = "https://exhentai.org" + parse_gallery_identifier(); } linkerDiv.append(createLink("linker", linker, "To ExHentai")); } else { if (document.location.href == 'https://exhentai.org/upload/manage.php') { linker = "https://upload.e-hentai.org/manage.php"; } else { linker = "https://e-hentai.org" + parse_gallery_identifier(); } linkerDiv.append(createLink("linker", linker, "To E-Hentai")); } // Add option to switch between E-Hentai and ExHentai in the top bar of the page document.getElementById('linker').addEventListener("click", function () { document.location.href = linker; }); // Setting page if (currentPageLink.indexOf("uconfig") > -1) { optionDiv.show(); var optionArray = []; optionArray.push(createOptionWithClass("loadSettingOption", "Load saved user setting", "setting")); optionArray.push(createOptionWithClass("saveSettingOption", "Save current user setting", "setting")); for (i = 0; i < optionArray.length; i++) { $('#optionDivUL').append(optionArray[i]); } document.getElementById('loadSettingOption').addEventListener("click", function () { var setting = GM_getValue("userSetting", ""); if (setting !== "") { if (document.location.href.indexOf('exhentai') !== - 1) { Cookies.set("uconfig", setting, { domain: ".exhentai.org", expires: 365 }); } else { Cookies.set("uconfig", setting, { domain: ".e-hentai.org", expires: 365 }); } alert("User setting loaded"); location.reload(); } else { alert("Nothing to load"); } }); document.getElementById('saveSettingOption').addEventListener("click", function () { GM_setValue("userSetting", Cookies.get("uconfig")); // Maybe have an option to save it to file alert("User setting saved"); }); } // Gallery page if (currentPageLink.indexOf("/g/") > -1 || currentPageLink.indexOf("/s/") > -1) { var indexMatch = getIndex_rlList(parse_gallery_identifier()); if (indexMatch.exactMatch === true && readLaterList[indexMatch.index].thumbnailLink !== "undefined") { $('#readLaterOptionDivUL').append(createOption("addReadLaterOption", 'Already in "view later" list')); $('#addReadLaterOption').css({ 'text-decoration': 'none', 'cursor': 'default', }); } else { $('#readLaterOptionDivUL').append(createOption("addReadLaterOption", 'Add to "view later" list')); document.getElementById('addReadLaterOption').addEventListener("click", add_rlEntryFunction); } if (indexMatch.index > -1) { $('#readLaterOptionDivUL').append(createOption("removeReadLaterOption", 'Remove from "view later" list')); document.getElementById('removeReadLaterOption').addEventListener("click", remove_rlEntryFunction); } if (currentPageLink.indexOf("/s/") > -1) { var successDiv; if (targetWebsite === "E-Hentai") { $('#i1').prepend('<div id="mpvAddon" class="dark"></div>'); $('#mpvAddon').append('<img id="mpvSave_rl" src="http://i.imgur.com/rdXO8o2.png" title="Save this page to view later list (E<->Ex extension)" style="margin-top:10px; opacity:0.8">'); $('#mpvAddon').append('<img id="mpvView_rl" src="http://i.imgur.com/ywCl5NP.png" title="Open view later list (E<->Ex extension)" style="margin-top:5px; opacity:0.8">'); successDiv = '<div id="successDiv" class="dark">Added/updated "view later" list</div>'; } else { $('#i1').prepend('<div id="mpvAddon" class="light"></div>'); $('#mpvAddon').append('<img id="mpvSave_rl" src="http://i.imgur.com/tWBUjde.png" title="Save this page to view later list (E<->Ex extension)" style="margin-top:10px; opacity:0.8">'); $('#mpvAddon').append('<img id="mpvView_rl" src="http://i.imgur.com/XH8qCCi.png" title="Open view later list (E<->Ex extension)" style="margin-top:5px; opacity:0.8">'); successDiv = '<div id="successDiv" class="light">Added/updated "view later" list</div>'; } $('body').append(successDiv); successDiv = $('#successDiv'); successDiv.hide(); document.getElementById('mpvSave_rl').addEventListener("click", add_rlEntryFunction); document.getElementById('mpvView_rl').addEventListener("click", view_rlButtonClick); hideFixedDivContent(); var oldLocation = location.href; setInterval(function () { if (location.href !== oldLocation) { oldLocation = location.href; $('#addReadLaterOption').text('Add to "view later" list'); document.getElementById('addReadLaterOption').addEventListener("click", add_rlEntryFunction); $('#addReadLaterOption').css({ 'text-decoration': 'underline', 'cursor': 'pointer', }); } }, 2000); // check 2 seconds } } $('#readLaterOptionDivUL').append(createOption("seeReadLaterListOption", 'Show "view later" list')); document.getElementById('seeReadLaterListOption').addEventListener("click", view_rlButtonClick); // If there is no option available, hide the optionDiv completely if ($('.setting').length === 0) { optionDiv.hide(); } $('#readLaterOptionDivUL').append(createOption("export_rlListOption", 'Export list')); document.getElementById('export_rlListOption').addEventListener("click", exportFunction); $('#readLaterOptionDivUL').append(createOption("import_rlListOption", 'Import list')); document.getElementById('import_rlListOption').addEventListener("click", importFunction); $('#readLaterOptionDivUL').append(createOption("reset_rlListOption", 'Empty the list')); document.getElementById('reset_rlListOption').addEventListener("click", resetList); } else { var successDiv; if (targetWebsite === "E-Hentai") { $('#bar3').append('<div id="mpvAddon" class="dark"></div>'); $('#mpvAddon').append('<img id="mpvSave_rl" src="http://i.imgur.com/rdXO8o2.png" title="Save this page to view later list (E<->Ex extension)" style="margin-top:10px; opacity:0.8">'); $('#mpvAddon').append('<img id="mpvView_rl" src="http://i.imgur.com/ywCl5NP.png" title="Open view later list (E<->Ex extension)" style="margin-top:5px; opacity:0.8">'); successDiv = '<div id="successDiv" class="dark">Added/updated "view later" list</div>'; } else { $('#bar3').append('<div id="mpvAddon" class="light"></div>'); $('#mpvAddon').append('<img id="mpvSave_rl" src="http://i.imgur.com/tWBUjde.png" title="Save this page to view later list (E<->Ex extension)" style="margin-top:10px; opacity:0.8">'); $('#mpvAddon').append('<img id="mpvView_rl" src="http://i.imgur.com/XH8qCCi.png" title="Open view later list (E<->Ex extension)" style="margin-top:5px; opacity:0.8">'); successDiv = '<div id="successDiv" class="light">Added/updated "view later" list</div>'; } $('body').append(successDiv); successDiv = $('#successDiv'); successDiv.hide(); document.getElementById('mpvSave_rl').addEventListener("click", add_rlButtonClick); document.getElementById('mpvView_rl').addEventListener("click", view_rlButtonClick); $('#fixedDiv').hide(); } redoTheme(); } }); function resetList() { if (confirm("Are you sure you want to empty the list? You cannot undo this unless you export it first.")) { GM_setValue("readLater", ""); } } function add_rlButtonClick() { //for MPV var pos = getOffset(this); $('#successDiv').css({ 'top': pos.top + 12, 'left': pos.left - 12, }); var currentPageNum = 0; var currentScrollLocation = $('#pane_images').scrollTop(); var allImgDiv = $('#pane_images_inner').children('div'); for (i = 0; i < allImgDiv.length; i++) { currentScrollLocation -= allImgDiv[i].offsetHeight; currentPageNum++; if (currentScrollLocation <= 0) { break; } } var lastPage = document.getElementById("pane_thumbs_inner").childElementCount; var title = document.title.substring(0, document.title.lastIndexOf(" - ")) + " {" + currentPageNum + "/" + lastPage + "}"; var link = parse_gallery_identifier(); link = link.substring(0, link.lastIndexOf("/")) + "/#page" + currentPageNum; var mainPage_URL = window.location.href.substring(0, window.location.href.lastIndexOf("/")).replace("mpv", "g"); var thumbnailLink; $(document).ajaxComplete(function (event, xhr, settings) { var data = xhr.responseText; var divStyle = $("#gd1", data).children('div').attr("style").split(" "); if (divStyle[3].startsWith("url")) { thumbnailLink = divStyle[3].substring(divStyle[3].indexOf("(") + 1, divStyle[3].indexOf(")")); } else { for (i = 0; i < stuff.length; i++) { if (divStyle[i].startsWith("url")) { thumbnailLink = divStyle[i].substring(divStyle[i].indexOf("(") + 1, divStyle[i].indexOf(")")); break; } } } thumbnailLink = thumbnailLink.replace("exhentai.org", "ehgt.org"); add_rlEntry(title, link, thumbnailLink); populate_rlDiv(); $('#successDiv').fadeIn(); setTimeout(function () { $('#successDiv').fadeOut(); }, 2000); }); $.ajax(mainPage_URL); } function exportFunction() { var str = rlArrayToString(readLaterList); var filename = "eh_view_later_list"; var blob = new Blob([str], { type: "text/plain;charset=utf-8" }); saveAs(blob, filename + ".txt"); } function importFunction() { var input = document.createElement('input'); $(input).attr("type", "file"); input.addEventListener("change", function readSingleFile(e) { var file = e.target.files[0]; if (!file) { return; } var reader = new FileReader(); reader.onload = function (e) { var contents = e.target.result; GM_setValue("readLater", contents); populate_rlDiv(); var successDiv; successDiv = '<div id="successDiv" class="light">List successfully loaded</div>'; $('body').append(successDiv); successDiv = $('#successDiv'); successDiv.hide(); $('#successDiv').css({ 'top': 1 + 12, 'left': 1 - 12, }); $('#successDiv').fadeIn(); setTimeout(function () { $('#successDiv').fadeOut(); }, 2000); }; reader.readAsText(file); }, false); $(input).trigger('click'); } function view_rlButtonClick() { if ($('#readLaterDiv').is(":visible")) { hide_rlList(); } else { show_rlList(); populate_rlDiv(); } } function getGalleryID(pageHref) { var splitHref = pageHref.split("/"); if (pageHref.indexOf("/g/") > -1 || pageHref.indexOf("/mpv/") > -1) { return splitHref[2]; } else { return splitHref[3].substring(0, splitHref[3].indexOf("-")); } } function populate_rlDiv() { readLaterList = load_rlList(); console.log($('#readLaterDiv').is(':visible')); console.log($('.readLaterItem').length, readLaterList.length); if ($('#readLaterDiv').is(':visible') && ($('.readLaterItem').length === 0 || $('.readLaterItem').length !== readLaterList.length)) { $("#readLaterTable_wrapper").remove(); // remove existing ones and repopulate the list $('#readLaterTableWrapper').append( `<table id="readLaterTable" class="display" cellspacing="0" width="100%"> <thead> <tr> <th>Delete</th> <th>EH Link</th> <th>EX Link</th> <th>Title</th> <th>Circle</th> <th>Artist</th> <th>Event</th> </tr> </thead> <tbody id="readLaterTableBody"> </tbody> </table>` ); $("#rlDivHeader").text("Read Later List: (" + readLaterList.length + " items)"); for (i = 0; i < readLaterList.length; i++) { var entryDOM = '<tr class="readLaterItem hoverPopup light" id="item' + i + '">'; if (readLaterList[i] !== null) { entryDOM += '<td class="readLaterRemoveItem option light">Remove</td>'; entryDOM += '<td>' + createLink("", "https://e-hentai.org" + readLaterList[i].link, "Read") + '</td>'; entryDOM += '<td>' + createLink("", "https://exhentai.org" + readLaterList[i].link, "Read") + '</td>'; entryDOM += '<td>' + readLaterList[i].title + '</td>'; entryDOM += '<td>' + readLaterList[i].group + '</td>'; entryDOM += '<td>' + readLaterList[i].artist + '</td>'; entryDOM += '<td>' + readLaterList[i].eventName + '</td>'; } entryDOM += "</tr>" $('#readLaterTableBody').append(entryDOM); } $(".hoverPopup").mousemove(function (event) { //on previewDiv.css({ "left": event.clientX + "px", "top": event.clientY + "px", }); if (event.clientX > (document.getElementById('readLaterDiv').offsetWidth * 0.75)) { previewDiv.addClass("showLeft"); previewDiv.removeClass("showRight"); } else { previewDiv.addClass("showRight"); previewDiv.removeClass("showLeft"); } previewDiv.show(); var arrayNumber = $(this).attr('id').replace("item", ""); var thumbLink = readLaterList[arrayNumber].thumbnailLink; if (thumbLink !== undefined && thumbLink !== "" && thumbLink !== "undefined") { $("#previewImg").attr("src", thumbLink); } else { $("#previewImg").attr("src", ""); $("#placeholderText").text("Sorry, please re-add the gallery to see thumbnail"); previewDiv.css("width", "160px"); } $(this).addClass('highlighted'); }); $(".hoverPopup").mouseleave(function (event) { //off previewDiv.hide(); $("#placeholderText").text(""); previewDiv.css("width", ""); $(this).removeClass('highlighted'); }); var removeItem = document.getElementsByClassName("readLaterRemoveItem"); for (i = 0; i < removeItem.length; i++) { removeItem[i].addEventListener("click", function () { //this.parentNode.remove(this); remove_rlEntry(parse_gallery_identifier(this.nextElementSibling.children[0].href)); }); } redoTheme(); dataTable = $('#readLaterTable').DataTable({ "scrollY": "400px", "scrollCollapse": true, "paging": false, "responsive": true, "bAutoWidth": true, }); // setTimeout(function () { // $('th')[0].click(); // }, 100) } } function remove_rlEntryFunction(event) { remove_rlEntry(parse_gallery_identifier()); $(this).parent().remove(); } function add_rlEntryFunction() { var title; if (window.location.href.indexOf("/g/") > -1) { title = $('#gn').text(); } else { title = $('#i1').children('h1').text() + " {" + $('#i2').children('.sn').children('div').text().replace(/ /g, "") + "}"; } var thumbnailLink; if (currentPageLink.indexOf("/s/") > -1) { var mainPage_URL = $('#i5').children('.sb').children('a').attr('href'); $(document).ajaxComplete(function (event, xhr, settings) { var data = xhr.responseText; var divStyle = $("#gd1", data).children('div').attr("style").split(" "); if (divStyle[3].startsWith("url")) { thumbnailLink = divStyle[3].substring(divStyle[3].indexOf("(") + 1, divStyle[3].indexOf(")")); } else { for (i = 0; i < stuff.length; i++) { if (divStyle[i].startsWith("url")) { thumbnailLink = divStyle[i].substring(divStyle[i].indexOf("(") + 1, divStyle[i].indexOf(")")); break; } } } thumbnailLink = thumbnailLink.replace("exhentai.org", "ehgt.org"); add_rlEntry(title, parse_gallery_identifier(), thumbnailLink); populate_rlDiv(); $('#successDiv').fadeIn(); setTimeout(function () { $('#successDiv').fadeOut(); }, 2000); $('#addReadLaterOption').text('Added to list'); $('#addReadLaterOption').off(); $('#addReadLaterOption').css({ 'text-decoration': 'none', 'cursor': 'default', }); }); $.ajax(mainPage_URL); } else { var divStyle = $("#gd1").children('div').attr("style").split(" "); if (divStyle[3].startsWith("url")) { thumbnailLink = divStyle[3].substring(divStyle[3].indexOf("(") + 1, divStyle[3].indexOf(")")); } else { for (i = 0; i < stuff.length; i++) { if (divStyle[i].startsWith("url")) { thumbnailLink = divStyle[i].substring(divStyle[i].indexOf("(") + 1, divStyle[i].indexOf(")")); break; } } } thumbnailLink = thumbnailLink.replace("exhentai.org", "ehgt.org"); add_rlEntry(title, parse_gallery_identifier(), thumbnailLink); populate_rlDiv(); $('#addReadLaterOption').text('Added to list'); $('#addReadLaterOption').off(); $('#addReadLaterOption').css({ 'text-decoration': 'none', 'cursor': 'default', }); } } function show_rlList() { readLaterDiv.show(); $('#seeReadLaterListOption').text('Hide "view later" list'); } function hide_rlList() { readLaterDiv.hide(); $('#seeReadLaterListOption').text('Show "view later" list'); } function createLink(id, link, text) { return '<a id="' + id + '" href="' + link + '" class="link light">' + text + '</a>'; } function createOption(id, text) { return '<li><label id="' + id + '" class="option light">' + text + '</label></li>'; } function createOptionWithClass(id, text, extraClass) { return '<li><label id="' + id + '" class="option light ' + extraClass + '">' + text + '</label></li>'; } function rlStringToArray(string) { var returnArray = []; var splitString = string.split(";"); for (i = 0; i < splitString.length; i++) { var entrySplit = splitString[i].split("::"); var entry = create_rlEntry(entrySplit[0], entrySplit[1], entrySplit[2]); if (entry !== null) { returnArray.push(entry); } } return returnArray; } function rlArrayToString(array) { var returnString = ""; for (i = 0; i < array.length; i++) { returnString += getStringEntry(array[i]); if (i !== (array.length - 1)) { returnString += ";"; } } return returnString; } function create_rlEntry(title, link, thumbnailLink) { if (!link || !title || !thumbnailLink) { return null; } else { titleParse = parseTitle(title); return { eventName: titleParse.eventName, group: titleParse.group, artist: titleParse.artist, title: titleParse.title, link: link, thumbnailLink: thumbnailLink }; } } function getStringEntry(entry) { var returnString = unparseTitle(entry) returnString += "::" + entry.link; returnString += "::" + entry.thumbnailLink; return returnString; } function load_rlList() { var rlString = GM_getValue("readLater", ""); return rlStringToArray(rlString); } function add_rlEntry(title, link, thumbnailLink) { titleParsed = parseTitle(title); if (getIndex_rlList(link).index === -1) { var entry = create_rlEntry(title, link, thumbnailLink); var entryString = title + "::" + link + "::" + thumbnailLink; // add to current saved list readLaterList.push(entry); // add to GM_saved list var newValue = GM_getValue("readLater", ""); if (newValue !== "") { newValue += ";"; } newValue += entryString; GM_setValue("readLater", newValue); } else { var replaceItemIndex = getIndex_rlList(link).index; // update current saved list readLaterList[replaceItemIndex].eventName = titleParsed.eventName; readLaterList[replaceItemIndex].group = titleParsed.group; readLaterList[replaceItemIndex].artist = titleParsed.artist; readLaterList[replaceItemIndex].title = titleParsed.title; readLaterList[replaceItemIndex].link = link; readLaterList[replaceItemIndex].thumbnailLink = thumbnailLink; // update current saved list var savedValue = GM_getValue("readLater", ""); var array = rlStringToArray(savedValue); array[replaceItemIndex].eventName = titleParsed.eventName; array[replaceItemIndex].group = titleParsed.group; array[replaceItemIndex].artist = titleParsed.artist; array[replaceItemIndex].title = titleParsed.title; array[replaceItemIndex].link = link; array[replaceItemIndex].thumbnailLink = thumbnailLink; savedValue = rlArrayToString(array); GM_setValue("readLater", savedValue); } } function remove_rlEntry(link) { var removeItemIndex = getIndex_rlList(link).index; // remove from current saved list readLaterList.splice(removeItemIndex, 1); // remove from GM_saved list var savedValue = GM_getValue("readLater", ""); var array = rlStringToArray(savedValue); array.splice(removeItemIndex, 1); savedValue = rlArrayToString(array); GM_setValue("readLater", savedValue); if (location.href.indexOf(link) > -1) { $('#addReadLaterOption').text('Add to "view later" list'); if (currentPageLink.indexOf("/mpv/") === -1) { document.getElementById('addReadLaterOption').addEventListener("click", add_rlEntryFunction); } $('#addReadLaterOption').css({ 'text-decoration': 'underline', 'cursor': 'pointer', }); } if (document.getElementsByClassName("readLaterItem").length === 0) { hide_rlList(); } populate_rlDiv(); } function getIndex_rlList(link) { var galleryID = getGalleryID(link); for (i = 0; i < readLaterList.length; i++) { if (readLaterList[i].link !== undefined && readLaterList[i].link.indexOf(galleryID) > -1) { if (readLaterList[i].link === link) { return { index: i, exactMatch: true }; } else { return { index: i, exactMatch: false }; } } } return { index: -1, exactMatch: false }; } // Parse the gallery link function parse_gallery_identifier(link) { var identifier_start; var identifier_end; var identifier; if (link === undefined) { if (location.href.indexOf('e-hentai.org') !== - 1) { identifier_start = location.href.indexOf('e-hentai.org') + 12; } else if (location.href.indexOf('exhentai.org') !== - 1) { identifier_start = location.href.indexOf('exhentai.org') + 12; } identifier_end = location.href.length; identifier = location.href.substr(identifier_start, identifier_end); } else { if (link.indexOf('e-hentai.org') !== - 1) { identifier_start = link.indexOf('e-hentai.org') + 12; } else if (link.indexOf('exhentai.org') !== - 1) { identifier_start = link.indexOf('exhentai.org') + 12; } identifier_end = link.length; identifier = link.substr(identifier_start, identifier_end); } return identifier; } //////////////////////////////////////////////////////////////// // Parsing and unparsing title //////////////////////////////////////////////////////////////// function unparseTitle(parsedTitle) { var returnString = ""; if (parsedTitle.eventName !== "") { returnString += "(" + parsedTitle.eventName + ") "; } if (parsedTitle.group !== "" && parsedTitle.artist !== "") { returnString += "[" + parsedTitle.group + " (" + parsedTitle.artist + ")] "; } else if (parsedTitle.artist !== "") { returnString += "[" + parsedTitle.artist + "] "; } returnString += parsedTitle.title; return returnString; } function parseTitle(stringTitle) { var eventName = ""; var group = ""; var artist = ""; var title = ""; var title_done = false; var mode = ""; var temp = ""; for (j = 0; j < stringTitle.length; j++) { if (stringTitle[j] === "(" && mode === "") { mode = "event"; } else if (stringTitle[j] === ")" && mode === "event") { mode = ""; } else if (stringTitle[j] === "[" && mode === "") { mode = "info"; } else if (stringTitle[j] === "(" && mode === "info") { mode = "artist"; group = temp; } else if (stringTitle[j] === ")" && mode === "artist") { mode = "title"; } else if (stringTitle[j] === "]" && mode === "info") { mode = "title"; artist = temp; } else if (stringTitle[j] === "]" && stringTitle[j - 1] === ")") { mode = "title"; } else { switch (mode) { case "": title += stringTitle[j]; break; case "event": eventName += stringTitle[j]; break; case "info": temp += stringTitle[j]; break; case "artist": artist += stringTitle[j]; break; case "title": title += stringTitle[j]; break; } } } return { eventName: eventName.trim(), group: group.trim(), artist: artist.trim(), title: title.trim() }; } //////////////////////////////////////////////////////////////// // UI Related //////////////////////////////////////////////////////////////// function hideFixedDivContent() { $('#minmaxFixedDivButton').text("+"); $('#scriptTitleHeader').hide(); $('#linkerDiv').hide(); $('#readLaterOptionDiv').hide(); $('#optionDiv').hide(); } function showFixedDivContent() { $('#minmaxFixedDivButton').text("–"); $('#scriptTitleHeader').show(); $('#linkerDiv').show(); $('#readLaterOptionDiv').show(); if ($('.setting').length > 0) { $('#optionDiv').show(); } } function redoTheme() { if (theme === "dark") { $('.light').addClass("dark"); $('.light').removeClass("light"); } else { $('.dark').addClass("light"); $('.dark').removeClass("dark"); } } //////////////////////////////////////////////////////////////// // External codes //////////////////////////////////////////////////////////////// // Credit to Adam Grant: http://stackoverflow.com/questions/442404/retrieve-the-position-x-y-of-an-html-element function getOffset(el) { el = el.getBoundingClientRect(); return { left: el.left + window.scrollX, top: el.top + window.scrollY }; } /*! * JavaScript Cookie v2.1.3 * https://github.com/js-cookie/js-cookie * * Copyright 2006, 2015 Klaus Hartl & Fagner Brack * Released under the MIT license */ ; (function (factory) { var registeredInModuleLoader = false; if (typeof define === 'function' && define.amd) { define(factory); registeredInModuleLoader = true; } if (typeof exports === 'object') { module.exports = factory(); registeredInModuleLoader = true; } if (!registeredInModuleLoader) { var OldCookies = window.Cookies; var api = window.Cookies = factory(); api.noConflict = function () { window.Cookies = OldCookies; return api; }; } }(function () { function extend() { var i = 0; var result = {}; for (; i < arguments.length; i++) { var attributes = arguments[i]; for (var key in attributes) { result[key] = attributes[key]; } } return result; } function init(converter) { function api(key, value, attributes) { var result; if (typeof document === 'undefined') { return; } // Write if (arguments.length > 1) { attributes = extend({ path: '/' }, api.defaults, attributes); if (typeof attributes.expires === 'number') { var expires = new Date(); expires.setMilliseconds(expires.getMilliseconds() + attributes.expires * 864e+5); attributes.expires = expires; } try { result = JSON.stringify(value); if (/^[\{\[]/.test(result)) { value = result; } } catch (e) { } if (!converter.write) { value = encodeURIComponent(String(value)) .replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g, decodeURIComponent); } else { value = converter.write(value, key); } key = encodeURIComponent(String(key)); key = key.replace(/%(23|24|26|2B|5E|60|7C)/g, decodeURIComponent); key = key.replace(/[\(\)]/g, escape); return (document.cookie = [ key, '=', value, attributes.expires ? '; expires=' + attributes.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE attributes.path ? '; path=' + attributes.path : '', attributes.domain ? '; domain=' + attributes.domain : '', attributes.secure ? '; secure' : '' ].join('')); } // Read if (!key) { result = {}; } // To prevent the for loop in the first place assign an empty array // in case there are no cookies at all. Also prevents odd result when // calling "get()" var cookies = document.cookie ? document.cookie.split('; ') : []; var rdecode = /(%[0-9A-Z]{2})+/g; var i = 0; for (; i < cookies.length; i++) { var parts = cookies[i].split('='); var cookie = parts.slice(1).join('='); if (cookie.charAt(0) === '"') { cookie = cookie.slice(1, -1); } try { var name = parts[0].replace(rdecode, decodeURIComponent); cookie = converter.read ? converter.read(cookie, name) : converter(cookie, name) || cookie.replace(rdecode, decodeURIComponent); if (this.json) { try { cookie = JSON.parse(cookie); } catch (e) { } } if (key === name) { result = cookie; break; } if (!key) { result[name] = cookie; } } catch (e) { } } return result; } api.set = api; api.get = function (key) { return api.call(api, key); }; api.getJSON = function () { return api.apply({ json: true }, [].slice.call(arguments)); }; api.defaults = {}; api.remove = function (key, attributes) { api(key, '', extend(attributes, { expires: -1 })); }; api.withConverter = init; return api; } return init(function () { }); }));