// ==UserScript==
// @name MangaDex Follows
// @namespace https://greasyfork.org/es/scripts/411685-mangadex-follows
// @version 1.3.7.1
// @description Manage your follows page
// @author Australis
// @match https://mangadex.org/*
// @exclude https://mangadex.org/chapter/*
// @grant GM_addStyle
// ==/UserScript==
GM_addStyle(".checkit::before {content: \"❌❌ \";}")
const debug = false
function log(string){
if(debug) console.log(string)
}
log("Executing");
function LoadLists(input){
let dalist = []
try{
if(localStorage.getItem(input)) dalist = JSON.parse(localStorage.getItem(input))
log(input+" loaded")
}
catch(e){
log("failed to load "+input)
}
return dalist
}
series = LoadLists('series')
const blacklist = LoadLists('blacklist')
const whitelist = LoadLists('whitelist')
const gap = LoadLists('gap')
var enhance;
try{
if(localStorage.getItem("enhance") != null) enhance = JSON.parse(localStorage.getItem("enhance"))
else enhance = true
}
catch(e){
enhance = true
}
checker = []
let nodes = []
function Checker(node){
if(checker.length == 0) checker = [node]
else checker.push(node)
log(node)
}
function CleanChecker(id,r){
try{
if(nodes.lenght == 0) nodes.push([id,[r]])
else{
add = true
for(let n of nodes){
log("a node")
if(n[0] == id) {
log("existing node")
n[1].push(r)
add = false
}
}
if(add) nodes.push([id,[r]])
}
}catch(e){
log("CleanChecker error: "+e)
}
}
function Decider(){
log("Decider")
for(let n of nodes){
if(n[1].length > 1){
log("deciding")
var save_c = 100000
var save_v = 100000
var save_r = false
var best = []
log(n[1])
for(let m of n[1]){
// log("save_c "+save_c)
let dataset = m.children[2].childNodes[1].dataset
log("chapter "+dataset.chapter)
if(dataset.volume*1){
if(save_v > dataset.volume*1){
save_v = dataset.volume*1
save_c = dataset.chapter*1
save_r = m
best = []
}
else if(save_c > dataset.chapter*1){
log("next one?")
save_c = dataset.chapter*1
save_r = m
best = []
}
else if(save_c == dataset.chapter*1){
log("same")
if(!best.includes(save_r)) best.push(save_r)
if(!best.includes(m)) best.push(m)
}
}
else{
if(save_c > dataset.chapter*1){
log("next one?")
save_c = dataset.chapter*1
save_r = m
best = []
}
else if(save_c == dataset.chapter*1){
log("same")
if(!best.includes(save_r)) best.push(save_r)
if(!best.includes(m)) best.push(m)
}
else log("no coincidence")
}
}
if(best.length){
for(let b of best) CleanCheckerB(n[0]*1,b)
}
else CleanCheckerB(n[0]*1,save_r)
}
else {
CleanCheckerB(n[0]*1,n[1][0])
}
}
return true
}
function CleanCheckerB(id,row){
try{
for(var x=checker.length-1; x>=0; x--){
if(checker[x][0] == id && checker[x][1] == row) checker.splice(x,1)
}
}catch(e){
log("CleanChecker error: "+e)
checker = []
}
}
function Ahead(){
if(checker.length){
for(c of checker){
c[1].getElementsByClassName("chapter_mark_read_button grey")[0].setAttribute("class","chapter_mark_read_button")
c[1].getElementsByClassName("chapter_mark_read_button")[0].setAttribute("style","color: red")
}
}
checker = []
}
function FS(array, number){//FindSeries
return array.findIndex(q => q[0]*1 == number*1)
}
//add titles from follows
if(document.URL.includes('mangadex.org/follows/manga')){
series_col = document.getElementsByClassName("manga-entry border-bottom");
for(var s of series_col){
var row = s.getElementsByClassName("row m-0")[1];
var name = row.children[0].innerText;
var state = row.children[2].innerText;
var id = s.dataset.id;
var node = [id,name,state,0,0]
var add = true;
if(series){
for(var m of series){
if(m[0] === id){
add = false;
if(m[2] !== state) m[2] = state;
}
}
if(add) series.push(node);
}
else series = [node]
}
localStorage.setItem('series',JSON.stringify(series))
}
else if(document.URL.includes('mangadex.org/follows')){
//read chapters
row = document.getElementsByClassName("chapter-container")[0].children;
function Hide(DataSet){
for(var b of blacklist){
if(b[0] == DataSet.mangaId && b[1] == DataSet.group) return true
}
return false
}
function OnlyThis(DataSet){
for(var w of whitelist){
if(w[0] == DataSet.mangaId && w[1] != DataSet.group) return 0
if(w[0] == DataSet.mangaId && w[1] == DataSet.group) return 1
}
return 2
}
let changeH = false
let changeO = false
for(var r of row){
let dataset = r.children[2].childNodes[1].dataset;
if(dataset.mangaId){
let manga_id = dataset.mangaId*1;
if(enhance) try{
if(Hide(dataset)) {
title = r.children[0].innerHTML
r.setAttribute("style","display: none")
changeH = true
}
else if(changeH){
title2 = r.children[0].innerHTML
if(r.children[0].classList.contains("d-md-flex")) r.children[0].innerHTML = title
title = title2
changeH = false
}
if(!OnlyThis(dataset)) {
title = r.children[0].innerHTML
r.setAttribute("style","display: none")
changeO = true
}
else if(changeO){
title2 = r.children[0].innerHTML
if(r.children[0].classList.contains("d-md-flex")) r.children[0].innerHTML = title
title = title2
changeO = false
}
}catch(e){
log("enhance error, "+e)
}
try{
pointer = FS(series,manga_id)
if(series[pointer][3].toString().includes("v")){//if is divided by volume
if(series[pointer][3].toString() == "0v0") r.children[0].classList.value += " checkit"
log("a volume one, "+series[FS(series,manga_id)][3])
q = series[pointer][3].split("v")
vol = q[0]
chap = q[1]
if(r.innerHTML.includes("mark_unread")){
if(chap*1 < dataset.chapter*1 && vol*1 == dataset.volume*1) {
log("new chapter")
series[pointer][3] = dataset.volume+"v"+dataset.chapter;
}
if(vol < dataset.volume*1) {
log("new volume")
series[pointer][3] = dataset.volume+"v"+dataset.chapter;
}
}
else if(enhance){
if((chap*1 >= dataset.chapter*1 && vol*1 == dataset.volume*1) || vol*1 > dataset.volume*1){ //a duplicate
r.getElementsByClassName("chapter_mark_read_button grey")[0].setAttribute("class","chapter_mark_read_button")
if(gap.findIndex(q => q[0]*1 == manga_id) >= 0){
let lgap = gap[gap.findIndex(q => q[0]*1 == dataset.mangaId)][1]
log("a gapped one: ",lgap)
log("current chapter: "+dataset.volume+"v"+dataset.chapter)
if(chap*1 >= lgap[0].split("v")[1] && vol*1>= lgap[0].split("v")[0] &&
lgap[1].split("v")[1] >= dataset.chapter*1 && vol*1<= lgap[1].split("v")[0]) r.getElementsByClassName("chapter_mark_read_button")[0].setAttribute("style","color: green")
}
else if(!(dataset.title.toLowerCase().includes("extra") || dataset.title.toLowerCase().includes("omake"))){
r.getElementsByClassName("chapter_mark_read_button")[0].setAttribute("style","color: blue")
}
else r.getElementsByClassName("chapter_mark_read_button")[0].setAttribute("style","color: green")
}
else{//a new one
if(chap*1 < dataset.chapter*1+1.11 && vol*1 == dataset.volume*1){//skipped chapter
Checker([manga_id,r])
}
if(chap*1 < dataset.chapter*1 && vol*1 == dataset.volume*1 && dataset.chapter*1 <= chap*1+1.11){//next chapter
// CleanChecker(manga_id)
CleanChecker(manga_id,r)
}
}
}
}
else{//if not divided by volume
this_last = series[FS(series,manga_id)][3]*1
if(r.innerHTML.includes("mark_unread")){
if(this_last < dataset.chapter*1) series[FS(series,manga_id)][3] = dataset.chapter*1;
}
else if(enhance){
if(this_last == 0) r.children[0].classList.value += " checkit"
if(this_last >= dataset.chapter*1){ //a duplicate
log("a duplicate")
r.getElementsByClassName("chapter_mark_read_button grey")[0].setAttribute("class","chapter_mark_read_button")
if(gap.findIndex(q => q[0]*1 == manga_id) >= 0){
let lgap = gap[gap.findIndex(q => q[0]*1 == dataset.mangaId)][1]
log("a gapped one: ",lgap)
log("current chapter: "+dataset.chapter)
if(dataset.chapter*1 >= lgap[0] &&
lgap[1] >= dataset.chapter*1) r.getElementsByClassName("chapter_mark_read_button")[0].setAttribute("style","color: green")
}
else if(dataset.title.toLowerCase().includes("extra") || dataset.title.toLowerCase().includes("omake") || (dataset.chapter*1)%1 == 0.5){
r.getElementsByClassName("chapter_mark_read_button")[0].setAttribute("style","color: green")
}
else r.getElementsByClassName("chapter_mark_read_button")[0].setAttribute("style","color: blue")
}
else{//a new one
if(this_last != 0
&& this_last < dataset.chapter*1+1.11){//skipped chapter
// if((dataset.chapter*1)%1 && series[FS(series,manga_id)][3]*1+0.1 <= dataset.chapter*1) log("skipped parted chapter")
Checker([manga_id,r])
}
if(this_last < dataset.chapter*1
&& dataset.chapter*1 <= this_last+1.11){//next chapter
if((dataset.chapter*1)%1 && dataset.chapter*1 == Math.round((this_last+0.1+Number.EPSILON)*10)/10) {//Math.round((18.3+0.1+Number.EPSILON)*10)/10
log("next parted chapter")
CleanChecker(manga_id,r)
}
else if((dataset.chapter*1)%1 && dataset.chapter*1 == this_last+0.5) {
log("next extra chapter")
CleanChecker(manga_id,r)
}
else if((dataset.chapter*1)%1 && this_last-this_last%1 < dataset.chapter*1-(dataset.chapter*1)%1
&& dataset.chapter*1 == this_last-this_last%1+1.1){
log("next new parted chapter")
CleanChecker(manga_id,r)
}
else if((dataset.chapter*1)%1 == 0) {
log("regular next chapter")
CleanChecker(manga_id,r)
}
}
}
}
}
}catch(e){
//series not included
log("series not included?\n"+e)
log(dataset.mangaId+" "+r.children[0].innerText)
let this_last = 0
if(r.innerHTML.includes("mark_unread")) this_last = dataset.chapter*1;
if(FS(series,dataset.mangaId) == -1) series.push([dataset.mangaId,r.children[0].innerText,' Reading',this_last,dataset.timestamp])
}
}//end if
}//end for
if(Decider()) Ahead()
localStorage.setItem('series',JSON.stringify(series))
}
if(document.URL.includes('/title/')){
log("title")
var follow_stat = document.getElementsByClassName("btn-group")[0].childNodes[0].childNodes[0].className;
let mangaId = document.URL.split("/")[4]*1
function ProcVol(){
try{
for(let t of temp){
[lastv,lastc] = last.split("v")
if(t.dataset != null){
let dataset = t.dataset;
let manga_id = dataset.mangaId;
let vol = dataset.volume*1
if(process && lastc == dataset.chapter*1 && lastv == vol){
if(!t.innerHTML.includes("mark_unread")){
last = "0v0"
log("reset")
}
else process = false
}
if(t.innerHTML.includes("mark_unread")) {
if(lastc < dataset.chapter*1 && lastv == vol) {//a new read chapter from same volume
last = vol+"v"+dataset.chapter
process = false
series[FS(series,manga_id)][3] = last;
}
if(lastv < vol){//a new volume is read
log("new volume")
last = vol+"v"+dataset.chapter
series[FS(series,manga_id)][3] = last;
}
if(time < dataset.timestamp*1){
time = dataset.timestamp*1
series[FS(series,manga_id)][4] = dataset.timestamp*1
}
}
}//end if
}//end for
log("done ProcVol, current last: "+last)
localStorage.setItem('series',JSON.stringify(series))
}catch(e){
log("ProcVol error\n"+e)
}
}
function Chapters(){
try{
if(last.toString().includes("v")){//is parted as independent chapters per volume
ProcVol()
}
else{//is default
for(let t of temp){
if(t.dataset != null){
let dataset = t.dataset;
let manga_id = dataset.mangaId;
let timestamp = dataset.timestamp
if(dataset.volume != null) {
vol = dataset.volume*1
}
else {
vol = 10000-1
}
if(checkvol && cvol > vol && cvol != 10000) {//volume change and not first iteration
if(cchp <= dataset.chapter*1){ //if it's not a successive chapter
log("volume!!")
checkvol = false
last = "0v0"
ProcVol()
}
}
if(!last.toString().includes("v")){
if(process && last == dataset.chapter*1){
if(!t.innerHTML.includes("mark_unread")){
last = 0
log("reset")
}
else process = false
}
if(t.innerHTML.includes("mark_unread")) {
if(last < dataset.chapter*1) {
process = false
last = dataset.chapter*1;
series[FS(series,manga_id)][3] = dataset.chapter*1;
}
if(time < dataset.timestamp*1){
time = dataset.timestamp*1
series[FS(series,manga_id)][4] = dataset.timestamp*1
}
}
cvol = vol
cchp = dataset.chapter*1
}//end if
}//end if
}//end for
log("new last: "+last)
localStorage.setItem('series',JSON.stringify(series))
log("OK");
}//end else
}catch(e){
log("Chapters error\n"+e)
}
}
var temp = document.getElementsByClassName("chapter-row d-flex row no-gutters p-2 align-items-center border-bottom odd-row");
var last = 0
var time = 0
var pos = FS(series,mangaId)
if(pos >= 0) {
last = series[pos][3]
if(series[pos].length == 4) series[pos].push(time)
else time = series[pos][4]
}
log("old last: "+last)
process = true
var cvol = 10000
var cchp = 0
checkvol = true
let state = document.getElementsByClassName("btn dropdown-toggle")[0].getElementsByClassName("d-none d-xl-inline")[0].innerText
let name = document.title.split(" (Title)")[0]
let id = document.URL.split("/")[4]
let node = [id,name,state,last,time]
let add = true;
let z = FS(series,id)
if(z == -1){
series.push(node)
log(name+" added to series")
}
else{
if(series[z][2] !== state) series[z][2] = state;
}
if(!follow_stat.includes("fa-bookmark")){
Chapters()
}
}
if(document.URL.includes('mangadex.org/follows') && !document.URL.includes('mangadex.org/follows/manga')){
let data = [['ID','Series name','Status','Last Read','Last Update']].concat(series);
for(var d of data){
if(d[1].includes("\"")) d[1] = d[1].replaceAll("\"","|")
if(d[1].includes(";")) d[1] = d[1].replaceAll(";",":")
if(d.length == 5) d[4] = Date(d[4])
else d.push("Unknown")
}
// Building the CSV from the Data two-dimensional array
// Each column is separated by ";" and new line "\n" for next row
let csvContent = '';
data.forEach(function(infoArray, index) {
dataString = infoArray.join(';');
csvContent += index < data.length ? dataString + '\n' : dataString;
});
// The download function takes a CSV string, the filename and mimeType as parameters
// Scroll/look down at the bottom of this snippet to see how download is called
let download = function(content, fileName, mimeType) {
var a = document.createElement('a');
mimeType = mimeType || 'application/octet-stream';
if (navigator.msSaveBlob) { // IE10
navigator.msSaveBlob(new Blob([content], {
type: mimeType
}), fileName);
} else if (URL && 'download' in a) { //html5 A[download]
a.href = URL.createObjectURL(new Blob([content], {
type: mimeType
}));
a.setAttribute('download', fileName);
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
} else {
location.href = 'data:application/octet-stream,' + encodeURIComponent(content); // only this mime type is supported
}
}
document.download = function(){download(csvContent, 'MangaDex.csv', 'text/csv;encoding:utf-8')}
let boton = document.createElement("li")
boton.setAttribute("class","nav-item")
boton.setAttribute("href","#")
boton.setAttribute("onclick","download()")
boton.appendChild(document.createElement("a"))
boton.children[0].setAttribute("class","nav-link")
boton.children[0].appendChild(document.createElement("span"))
boton.children[0].children[0].setAttribute("class","fas fa-download fa-fw")
boton.children[0].children[0].setAttribute("aria-hidden","true")
boton.children[0].appendChild(document.createElement("span"))
boton.children[0].children[1].setAttribute("class","d-none d-md-inline")
boton.children[0].children[1].innerText = "Export"
document.getElementsByClassName("nav nav-tabs")[0].insertBefore(boton,document.getElementsByClassName("nav nav-tabs")[0].children[4])
let boton2 = document.createElement("li")
boton2.appendChild(document.createElement("a"))
boton2.firstChild.setAttribute("class","nav-link")
boton2.firstChild.innerText = "Script Options"
boton2.firstChild.setAttribute("onclick","Show()")
document.getElementsByClassName("nav nav-tabs")[0].insertBefore(boton2,document.getElementsByClassName("nav nav-tabs")[0].children[5])
}
function CreateMenu(){
gg = document.createElement("style")
gg.innerText = ".modal_row {display: grid;grid-gap: 5px;grid-template-columns: 20vw 20vw 5vw;}"
gg.innerText+= ".modalX {display: none;position: fixed;z-index: 10;padding-top: 10vh;left: 0;top: 0;width: 99%; height: 100%; overflow: auto; background-color: rgb(0,0,0); background-color: rgba(0,0,0,0.4); color: white;}"
gg.innerText+= ".modalo {position: relative;background-color: black;margin: auto;padding: 2vw;border: 1px solid #888;width: 80%;box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19);-webkit-animation-name: animatetop;-webkit-animation-duration: 0.4s;animation-name: animatetop;animation-duration: 0.4s}"
gg.innerText+= "@-webkit-keyframes animatetop {from {top:-300px; opacity:0} to {top:0; opacity:1}}"
gg.innerText+= "@keyframes animatetop {from {top:-300px; opacity:0}to {top:0; opacity:1}}"
gg.innerText+= ".closex {color: white;float: right;font-size: 28px;font-weight: bold;padding-right: 8vw;}"
gg.innerText+= ".closex:hover,.close:focus {color: #000;text-decoration: none;cursor: pointer;}"
gg.innerText+= ".half {width: 45%;display: inline-block;}"
document.querySelector("head").appendChild(gg)
modal = document.createElement("div")
modal.setAttribute("class","modalX")
modal.setAttribute("id","modalX")
// modal.setAttribute("style","margin: auto;width: 70vw;")
closer = document.createElement("span")
closer.setAttribute("class","closex")
closer.innerText = "×"
closer.setAttribute("onclick","CloseThis()")
modal.appendChild(closer)
form = document.createElement("div")
elem1 = document.createElement("div") //checkbox
elem2 = document.createElement("div") //whitelist
elem3 = document.createElement("div") //blacklist
elem4 = document.createElement("div") //gap
modbut = document.createElement("button") //save button
canbut = document.createElement("button") //cancel button
modt1 = document.createElement("h2") //title1
modt1.setAttribute("title","series & group ID are the numbers in their URLs, after /title/ and /group/ respectively")
modt1.innerText = "Whitelist elements"
modt2 = document.createElement("h2") //title2
modt2.setAttribute("title","series & group ID are the numbers in their URLs, after /title/ and /group/ respectively")
modt2.innerText = "Blacklist elements"
modt3 = document.createElement("h2") //title3
modt3.setAttribute("title","series ID are the numbers after /title/ in their URL, and the gap has to include the chapters available between the gap")
modt3.innerText = "Gap list elements"
form.setAttribute("class","modalo")
form.setAttribute("id","ScriptForm")
// form.setAttribute("action","")
elem1A = document.createElement("input")
elem1A.setAttribute("type","checkbox")
elem1A.setAttribute("id","enhancer")
elem1A.setAttribute("name","enhancer")
elem1A.setAttribute("style","margin:5px;")
elem1A.setAttribute("checked",enhance)
elem1B = document.createElement("label")
elem1B.setAttribute("for","enhancer")
elem1B.innerText = "\tHighlight unread chapters"
elem1.appendChild(elem1A)
elem1.appendChild(elem1B)
elem2.setAttribute("id","whitelister")
elem2.setAttribute("style","display:grid;grid-gap:5px;")
modalrow1 = document.createElement("div")
modalrow1.setAttribute("class","modal_row")
title2A = document.createElement("span")
title2B = document.createElement("span")
title2A.innerText = "series ID"
title2B.innerText = "group ID"
modalrow1.appendChild(title2A)
modalrow1.appendChild(title2B)
elem2.appendChild(modt1)
elem2.appendChild(modalrow1)
function Row1(w){
let modalrow2 = document.createElement("div")
modalrow2.setAttribute("class","modal_row")
let span2A = document.createElement("span")
let input2A = document.createElement("input")
input2A.setAttribute("type","number")
input2A.setAttribute("name","mangaID")
input2A.setAttribute("value",w[0])
span2A.appendChild(input2A)
let span2B = document.createElement("span")
let input2B = document.createElement("input")
input2B.setAttribute("type","number")
input2B.setAttribute("name","groupID")
input2B.setAttribute("value",w[1])
span2B.appendChild(input2B)
modalrow2.appendChild(span2A)
modalrow2.appendChild(span2B)
let del = document.createElement("p")
del.innerText = "DELETE"
del.setAttribute("onclick","this.parentElement.remove()")
modalrow2.appendChild(del)
return modalrow2
}
if(whitelist.length) for(let w of whitelist){
elem2.appendChild(Row1(w))
// let modalrow2 = document.createElement("div")
// modalrow2.setAttribute("class","modal_row")
// let span2A = document.createElement("span")
// let input2A = document.createElement("input")
// input2A.setAttribute("type","number")
// input2A.setAttribute("name","mangaID")
// input2A.setAttribute("value",w[0])
// span2A.appendChild(input2A)
// let span2B = document.createElement("span")
// let input2B = document.createElement("input")
// input2B.setAttribute("type","number")
// input2B.setAttribute("name","groupID")
// input2B.setAttribute("value",w[1])
// span2B.appendChild(input2B)
// modalrow2.appendChild(span2A)
// modalrow2.appendChild(span2B)
// let del = document.createElement("p")
// del.innerText = "DELETE"
// del.setAttribute("onclick","this.parentElement.remove()")
// modalrow2.appendChild(del)
// elem2.appendChild(modalrow2)
}
// else{
// modalrow2 = document.createElement("div")
// modalrow2.setAttribute("class","modal_row")
// }
add = document.createElement("p")
add.setAttribute("id","adder")
add.innerText = "ADD NEW"
add.setAttribute("onclick","this.remove();AddWL(this)")
elem2.appendChild(add)
elem3.setAttribute("id","blacklister")
elem3.appendChild(modt2)
elem3.appendChild(modalrow1.cloneNode(true))
if(blacklist.length) for(let b of blacklist){
elem3.appendChild(Row1(b))
// let modalrow2 = document.createElement("div")
// modalrow2.setAttribute("class","modal_row")
// let span2A = document.createElement("span")
// let input2A = document.createElement("input")
// input2A.setAttribute("type","number")
// input2A.setAttribute("name","mangaID")
// input2A.setAttribute("value",b[0])
// span2A.appendChild(input2A)
// let span2B = document.createElement("span")
// let input2B = document.createElement("input")
// input2B.setAttribute("type","number")
// input2B.setAttribute("name","groupID")
// input2B.setAttribute("value",b[1])
// span2B.appendChild(input2B)
// modalrow2.appendChild(span2A)
// modalrow2.appendChild(span2B)
// let del = document.createElement("p")
// del.innerText = "DELETE"
// del.setAttribute("onclick","this.parentElement.remove()")
// modalrow2.appendChild(del)
// elem3.appendChild(modalrow2)
}
// else{
// modalrow2 = document.createElement("div")
// modalrow2.setAttribute("class","modal_row")
// }
add = document.createElement("p")
add.setAttribute("id","adder")
add.innerText = "ADD NEW"
add.setAttribute("onclick","this.remove();AddBL(this)")
elem3.appendChild(add)
elem4.setAttribute("id","gapper")
modalrow1 = document.createElement("div")
modalrow1.setAttribute("class","modal_row")
let title4A = document.createElement("span")
let title4B = document.createElement("span")
let title4B1 = document.createElement("span")
let title4B2 = document.createElement("span")
title4B1.setAttribute("class","half")
title4B2.setAttribute("class","half")
title4A.innerText = "series ID"
title4B1.innerText = "Gap start"
title4B2.innerText = "Gap end"
title4B.appendChild(title4B1)
title4B.appendChild(title4B2)
modalrow1.appendChild(title4A)
modalrow1.appendChild(title4B)
elem4.appendChild(modt3)
elem4.appendChild(modalrow1)
if(gap.length) for(let g of gap){
let modalrow2 = document.createElement("div")
modalrow2.setAttribute("class","modal_row")
let span2A = document.createElement("span")
let input2A = document.createElement("input")
input2A.setAttribute("type","number")
input2A.setAttribute("name","mangaIDgap")
input2A.setAttribute("value",g[0])
span2A.appendChild(input2A)
let span2B = document.createElement("span")
let span2B1 = document.createElement("span")
let span2B2 = document.createElement("span")
let input2B1 = document.createElement("input")
input2B1.setAttribute("type","number")
input2B1.setAttribute("class","half")
input2B1.setAttribute("name","gap1")
input2B1.setAttribute("value",g[1][0])
span2B.appendChild(input2B1)
span2B2 = document.createElement("span")
let input2B2 = document.createElement("input")
input2B2.setAttribute("type","number")
input2B2.setAttribute("class","half")
input2B2.setAttribute("name","gap2")
input2B2.setAttribute("value",g[1][1])
span2B.appendChild(input2B2)
modalrow2.appendChild(span2A)
modalrow2.appendChild(span2B)
let del = document.createElement("p")
del.innerText = "DELETE"
del.setAttribute("onclick","this.parentElement.remove()")
modalrow2.appendChild(del)
elem4.appendChild(modalrow2)
}
// else{
// modalrow2 = document.createElement("div")
// modalrow2.setAttribute("class","modal_row")
// }
add = document.createElement("p")
add.setAttribute("id","adder")
add.innerText = "ADD NEW"
add.setAttribute("onclick","this.remove();AddGap(this)")
elem4.appendChild(add)
form.appendChild(elem1)
form.appendChild(elem2)
form.appendChild(elem3)
form.appendChild(elem4)
modal.appendChild(form)
buttons = document.createElement("div")
modbut.setAttribute("onclick","UpdateValues()")
modbut.innerText = "Save Changes & Reload"
modbut.setAttribute("style","margin:auto;width:30%;display:block;")
buttons.appendChild(modbut)
canbut.setAttribute("onclick","CloseThis()")
canbut.innerText = "Exit without Saving Changes"
canbut.setAttribute("style","margin:auto;width:30%;display:block;")
buttons.appendChild(canbut)
form.appendChild(buttons)
document.querySelector("body").appendChild(modal)
}
CreateMenu()
function NewRow1(){
let modalrow2 = document.createElement("div")
modalrow2.setAttribute("class","modal_row")
let span2A = document.createElement("span")
let input2A = document.createElement("input")
input2A.setAttribute("type","number")
input2A.setAttribute("name","mangaID")
input2A.setAttribute("value",0)
span2A.appendChild(input2A)
let span2B = document.createElement("span")
let input2B = document.createElement("input")
input2B.setAttribute("type","number")
input2B.setAttribute("name","groupID")
input2B.setAttribute("value",0)
span2B.appendChild(input2B)
modalrow2.appendChild(span2A)
modalrow2.appendChild(span2B)
let del = document.createElement("p")
del.innerText = "DELETE"
del.setAttribute("onclick","this.parentElement.remove()")
modalrow2.appendChild(del)
return modalrow2
}
function NewRow2(){
let modalrow2 = document.createElement("div")
modalrow2.setAttribute("class","modal_row")
let span2A = document.createElement("span")
let input2A = document.createElement("input")
input2A.setAttribute("type","number")
input2A.setAttribute("name","mangaIDgap")
input2A.setAttribute("value",0)
span2A.appendChild(input2A)
let span2B = document.createElement("span")
let span2B1 = document.createElement("span")
let span2B2 = document.createElement("span")
let input2B1 = document.createElement("input")
input2B1.setAttribute("type","number")
input2B1.setAttribute("class","half")
input2B1.setAttribute("name","gap1")
input2B1.setAttribute("value",0)
span2B.appendChild(input2B1)
span2B2 = document.createElement("span")
let input2B2 = document.createElement("input")
input2B2.setAttribute("type","number")
input2B2.setAttribute("class","half")
input2B2.setAttribute("name","gap2")
input2B2.setAttribute("value",0)
span2B.appendChild(input2B2)
modalrow2.appendChild(span2A)
modalrow2.appendChild(span2B)
let del = document.createElement("p")
del.innerText = "DELETE"
del.setAttribute("onclick","this.parentElement.remove()")
modalrow2.appendChild(del)
return modalrow2
}
function NewButton(ToDo){
add = document.createElement("p")
add.setAttribute("id","adder")
add.setAttribute("onclick",ToDo)
add.innerText = "ADD NEW"
return add
}
document.Show = function(){
modalX.style.display = "block";
}
document.CloseThis = function(){
modalX.style.display = "none";
}
document.AddWL = function(element){
element.remove()
elem2.appendChild(NewRow1())
elem2.appendChild(NewButton("this.remove();AddWL(this)"))
}
document.AddBL = function(element){
element.remove()
elem3.appendChild(NewRow1())
elem3.appendChild(NewButton("this.remove();AddBL(this)"))
}
document.AddGap = function(element){
element.remove()
elem4.appendChild(NewRow2())
elem4.appendChild(NewButton("this.remove();AddGap(this)"))
}
document.UpdateValues = function() {
log("Updating")
var elements = document.getElementById("ScriptForm").children;
log(elements)
enhance = document.getElementById("ScriptForm").getElementsByTagName("input")[0].checked
obj1 =[];
obj2 =[];
obj3 =[];
let wl = elements[1].getElementsByClassName("modal_row")
let bl = elements[2].getElementsByClassName("modal_row")
let gl = elements[3].getElementsByClassName("modal_row")
for(let i = 1; i < wl.length; i++){
let inputs = wl[i].getElementsByTagName("input")
obj1.push([inputs.mangaID.value*1,inputs.groupID.value*1])
}
for(let i = 1; i < bl.length; i++){
let inputs = bl[i].getElementsByTagName("input")
obj2.push([inputs.mangaID.value*1,inputs.groupID.value*1])
}
for(let j = 1; j < gl.length; j++){
let spans = gl[j].getElementsByTagName("input")
obj3.push([spans.mangaIDgap.value*1,[spans.gap1.value*1,spans.gap2.value*1]])
}
localStorage.setItem('whitelist',JSON.stringify(obj1));
localStorage.setItem('blacklist',JSON.stringify(obj2));
localStorage.setItem('gap',JSON.stringify(obj3));
localStorage.setItem('enhance',JSON.stringify(enhance))
location.reload()
}