Untitled diff

Created Diff never expires
62 removals
Words removed130
Total words2168
Words removed (%)6.00
742 lines
44 additions
Words added78
Total words2116
Words added (%)3.69
735 lines
// ==UserScript==
// ==UserScript==
// @name EH Gallery Quick Favourite
// @name EH Gallery Quick Favourite
// @author FabulousCupcake
// @author FabulousCupcake
// @namespace http://fabulous.cupcake.jp.net/
// @namespace http://fabulous.cupcake.jp.net/
// @version v2.2.0
// @version v2.2.0f
// @description Upgrades the gallery favourite button to allow quick favouriting of a gallery.
// @description Upgrades the gallery favourite button to allow quick favouriting of a gallery.
// @include /^https?://(ex|(?:g\.)?e-)hentai\.org/g/\d+?/\w{10}/?/
// @include /^https?://(ex|(?:g\.)?e-)hentai\.org/g/\d+?/\w{10}/?/
// @include /^https?://(ex|(?:g\.)?e-)hentai\.org\/gallerypopups\.php\?.+&act=addfav/
// @include /^https?://(ex|(?:g\.)?e-)hentai\.org\/gallerypopups\.php\?.+&act=addfav/
// @grant none
// @grant GM.xmlHttpRequest
// ==/UserScript==
// ==/UserScript==


/* ====================================== *\
/* ====================================== *\
Hotkey Map
Hotkey Map
----
----
Shift+F : Initiate Favouriting Mode
Shift+F : Initiate Favouriting Mode
[0-9] : Favourite 0-9
[0-9] : Favourite 0-9
- : Remove Favourite
- : Remove Favourite
----
----
Pressing any other key during act-
Pressing any other key during act-
ive favouriting mode will exit the
ive favouriting mode will exit the
active favving mode.
active favving mode.
\* ====================================== */
\* ====================================== */




// Config
// Config
const config = {
const config = {
"debug": false,
"debug": false,
"editor_size": 60, // Width of the favnotes input element in not-px unit
"editor_size": 60, // Width of the favnotes input element in not-px unit
"hotkeys": true, // Enable hotkeys
"hotkeys": true, // Enable hotkeys
"cheatsheet": true // Show cheatsheet after pressing Shift+F?
"cheatsheet": true // Show cheatsheet after pressing Shift+F?
};
};


// Colors
// Colors
var geh = {
var geh = {
"border" : "#5C0D12",
"border" : "#5C0D12",
"bg" : "#E3E0D1",
"bg" : "#E3E0D1",
"bg_light" : "#F8F6EE",
"bg_light" : "#F8F6EE",
};
};
var exh = {
var exh = {
"border" : "#000000",
"border" : "#000000",
"bg" : "#4F535B",
"bg" : "#4F535B",
"bg_light" : "#5F636B",
"bg_light" : "#5F636B",
};
};
var color;
var color;
var hotkeyInit = false;
var hotkeyInit = false;


// Are we on fjords?
// Are we on fjords?
color = (location.host.substr(0,2) == "ex" ) ?
color = (location.host.substr(0,2) == "ex" ) ?
color = exh :
color = exh :
color = geh;
color = geh;


// Stylesheet
// Stylesheet
var stylesheet =`
var stylesheet =`
#gdf {
#gdf {
margin: 6px 0 !important;
margin: 6px 0 !important;
padding: 10px 5px !important;
padding: 10px 5px !important;
width: 160px !important;
width: 160px !important;
height: 18px;
height: 18px;
position: relative;
position: relative;
border: 1px dashed ${color.border};
border: 1px dashed ${color.border};
left: -2px !important;
left: -2px !important;
}
}


#gdf > div:nth-child(1),
#gdf > div:nth-child(1),
#gdf > div:nth-child(2),
#gdf > div:nth-child(2),
#gdf > div:nth-child(3) {
#gdf > div:nth-child(3) {
display: inline !important;
display: inline !important;
float: none !important;
float: none !important;
}
}


#gdf > div:nth-child(2) > a {
#gdf > div:nth-child(2) > a {
position: relative;
position: relative;
top: -1px;
top: -1px;
line-height: 21px;
line-height: 21px;
}
}


#gdf > #fav {
#gdf > #fav {
padding-left: 5px;
padding-left: 5px;
}
}


#gdf > #fav > * {
#gdf > #fav > * {
float: none !important;
float: none !important;
display: inline-block !important;
display: inline-block !important;
margin: 0 !important;
margin: 0 !important;
position: relative;
position: relative;
top: 2px;
top: 2px;
}
}


#gdf div.i {
#gdf div.i {
display: inline-block;
display: inline-block;
margin: 0 !important;
margin: 0 !important;
}
}


#gdf a:hover {
#gdf a:hover {
color: inherit !important;
color: inherit !important;
}
}


.qf-top, .qf-bot {
.qf-top, .qf-bot {
background: ${color.bg_light} !important;
background: ${color.bg_light} !important;
width: inherit;
width: inherit;
padding: 0 5px;
padding: 0 5px;
position: absolute;
position: absolute;
left: -1px;
left: -1px;
visibility: hidden;
visibility: hidden;
border: 1px solid ${color.border};
border: 1px solid ${color.border};
}
}


.qf-top {
.qf-top {
border-bottom: none;
border-bottom: none;
padding-top: 5px;
padding-top: 5px;
bottom: 33px;
bottom: 33px;
}
}


.qf-bot {
.qf-bot {
border-top: none;
border-top: none;
padding-bottom: 5px;
padding-bottom: 5px;
top: 33px;
top: 33px;
}
}


#gdf .fav {
#gdf .fav {
box-sizing: border-box;
box-sizing: border-box;
cursor: pointer;
cursor: pointer;
padding: 5px;
padding: 5px;
text-align: left;
text-align: left;
width: 100%;
width: 100%;
}
}


#gdf .fav:hover {
#gdf .fav:hover {
background: ${color.bg};
background: ${color.bg};
}
}


#gdf:hover,
#gdf:hover,
#gdf.hover {
#gdf.hover {
border: 1px solid ${color.border};
border: 1px solid ${color.border};
}
}


#gdf:hover > .qf-top,
#gdf:hover > .qf-top,
#gdf:hover > .qf-bot,
#gdf:hover > .qf-bot,
#gdf.hover > .qf-top,
#gdf.hover > .qf-top,
#gdf.hover > .qf-bot {
#gdf.hover > .qf-bot {
visibility: visible;
visibility: visible;
}
}


#gdf > .favnote {
#gdf > .favnote {
float: right !important;
float: right !important;
cursor: pointer;
cursor: pointer;
width: 16px;
width: 16px;
height: 16px;
height: 16px;
margin-right: 5px;
margin-right: 5px;
position: relative;
position: relative;
top: 1px;
top: 1px;
z-index: 20;
z-index: 20;
opacity: 0.5;
opacity: 0.5;
}
}


#gdf > .favnote:hover {
#gdf > .favnote:hover {
opacity: 1;
opacity: 1;
}
}


#gdf > .favnote:after {
#gdf > .favnote:after {
opacity: 0;
opacity: 0;
}
}


#gdf > .favnote:hover:after {
#gdf > .favnote:hover:after {
display: block;
display: block;
padding: 0 5px;
padding: 0 5px;
height: 20px;
height: 20px;
box-shadow: 0 1px 4px rgba(0,0,0,0.4);
box-shadow: 0 1px 4px rgba(0,0,0,0.4);
background: #f4f4f4;
background: #f4f4f4;
color: #333;
color: #333;
font-weight: 400;
font-weight: 400;
font-size: 11px;
font-size: 11px;
line-height: 20px;
line-height: 20px;
position: absolute;
position: absolute;
top: -20px;
top: -20px;
left: 0px;
left: 0px;
transition: opacity 300ms cubic-bezier(1, -1, 1, -1);
transition: opacity 300ms cubic-bezier(1, -1, 1, -1);
opacity: 1
opacity: 1
}
}


/* ========================================= *\
/* ========================================= *\
* Fugue Icons v3.5.6 by Yusuke Kamiyamane *
* Fugue Icons v3.5.6 by Yusuke Kamiyamane *
* http://p.yusukekamiyamane.com/ *
* http://p.yusukekamiyamane.com/ *
\* ========================================= */
\* ========================================= */
#gdf > .favnote { background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABQ0lEQVR4AcWONZoVURBGTxXusgrcIcMhw3dCjC/hxewB9wR3SXAYJGKS5zLW91bBK9wd/u6+2ud8P/89AnDjsOwBZvBjKS1a7xd4k+EAZsyav2zvFkst3A08Y1aQUz85D2C5AKC39ymdyhG9dlBkyUY/D6BvBIINYkUtvlw0sNTG8iCpSAwNFQwMDMS3eO2pLWZsvbJfln3YQEARkTdOi3nYsOG8TUpDNJtNzpzYDizZXHlxbQqwMv7IGRVRVBUz+6pk+vSFmGVGjx7N3XStCfCRQES+J4kmb5l3gpRRQhDQdyX6ah3Mxw0Euh/fkYRg1OcNBMWRcHxPosPHfNIgoUgXFtz5rkR1RDDvBH39PhKdiIwAcccxcCPWMVvA7hk3Q3RkMG8FU2/d4Vm7tHk0P5FHz3nWZQUYA0wI2c8lAS1+Ny8BF2m6Eor51N8AAAAASUVORK5CYII='); }
#gdf > .favnote { background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABQ0lEQVR4AcWONZoVURBGTxXusgrcIcMhw3dCjC/hxewB9wR3SXAYJGKS5zLW91bBK9wd/u6+2ud8P/89AnDjsOwBZvBjKS1a7xd4k+EAZsyav2zvFkst3A08Y1aQUz85D2C5AKC39ymdyhG9dlBkyUY/D6BvBIINYkUtvlw0sNTG8iCpSAwNFQwMDMS3eO2pLWZsvbJfln3YQEARkTdOi3nYsOG8TUpDNJtNzpzYDizZXHlxbQqwMv7IGRVRVBUz+6pk+vSFmGVGjx7N3XStCfCRQES+J4kmb5l3gpRRQhDQdyX6ah3Mxw0Euh/fkYRg1OcNBMWRcHxPosPHfNIgoUgXFtz5rkR1RDDvBH39PhKdiIwAcccxcCPWMVvA7hk3Q3RkMG8FU2/d4Vm7tHk0P5FHz3nWZQUYA0wI2c8lAS1+Ny8BF2m6Eor51N8AAAAASUVORK5CYII='); }
#gdf > .favnote.plus { background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABl0lEQVR4AcWOA4xeQRRGz0xtM6gd1DbCmjFquw3qWGVUx6lt27Ztt+vdN3OnndWPddTv4frk479LAVzfp5YATcmfVrbu585HAK7uUTtadF03WEwszgk4i0iANYlYm4TYAIBPn14S/2P/TmBF2wHuHIAGEEEhyUjwy3/Y4A9i4hCbjAkMKSkBSUlJ+K9Nn6ODRZhxeZfqClA4E4BGKYWPIPhYqFBhMmRMCjExMZw+PB9oO+jHx6sVgB6FAaxFK6XRWiMiOUKaNGmFiKV48eI8MFdjACIASqk8Id5Jxk0mwPgiFaAByROi/+X+BkCT6UDhvzAnEbWPM15fpveTw8x6cx0bDvA0hQZyh9z6/Y3WHftx8/fXKAcGTbqD7CBT7p+m06VtYBx/7B+UgbGubHvWV1yjADav5MyIUbu6IjHgHA7BOfG5j7Q7soqy3RsRrVM7T95QQMW5Y1jWsDZNyEEbi5So81oVKglQcUSLUj+33IpPcSR9f+n2A5QAqgI18/wWl7pT81Uz52P6TQkKpClF1zChyHUfSddf7UXJLEn3VbsAAAAASUVORK5CYII='); }
#gdf > .favnote.plus { background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABl0lEQVR4AcWOA4xeQRRGz0xtM6gd1DbCmjFquw3qWGVUx6lt27Ztt+vdN3OnndWPddTv4frk479LAVzfp5YATcmfVrbu585HAK7uUTtadF03WEwszgk4i0iANYlYm4TYAIBPn14S/2P/TmBF2wHuHIAGEEEhyUjwy3/Y4A9i4hCbjAkMKSkBSUlJ+K9Nn6ODRZhxeZfqClA4E4BGKYWPIPhYqFBhMmRMCjExMZw+PB9oO+jHx6sVgB6FAaxFK6XRWiMiOUKaNGmFiKV48eI8MFdjACIASqk8Id5Jxk0mwPgiFaAByROi/+X+BkCT6UDhvzAnEbWPM15fpveTw8x6cx0bDvA0hQZyh9z6/Y3WHftx8/fXKAcGTbqD7CBT7p+m06VtYBx/7B+UgbGubHvWV1yjADav5MyIUbu6IjHgHA7BOfG5j7Q7soqy3RsRrVM7T95QQMW5Y1jWsDZNyEEbi5So81oVKglQcUSLUj+33IpPcSR9f+n2A5QAqgI18/wWl7pT81Uz52P6TQkKpClF1zChyHUfSddf7UXJLEn3VbsAAAAASUVORK5CYII='); }
#gdf > .favnote.arrow { background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABnUlEQVR4Ac2QA6weURCFt7bduHZc27YV1bZt+9m2bdu2bRvn7Tz8ZthJvsXdPd+ducz/UeF2/V6zmMnIaiFBqE0/i7YqdbSU/URz6Xc0l3xBY9F71OU9Q3X2PVRm3ASR4L8H9C/LGj5BsFU/y7YKBTQVvkBjwTM05D9Ffd5j1GTfR3naLRQnXUFhwkVEuG8BGt1A/7Os5QgCLfpZtVUoobnopUSJl+UyDub/+nlxBH6m/WzaK1XQWvKaJFI7oXEowxF4G/Wz66hSQ1vpG5kkJKAMR+Cu38+ho1oD7WXvZJLQwVKGI3DR6efUWaOJjvL3UiUfnF1hF2YAynAEDpr9XFCjzQo+SJWc0Q/DWYMIvFE9HccR2Kr2c0OtDjorPgpJXlrY4JiqD4GjhIo3lAqAjV9saxa/jz7NUBn/ZnxQbwWSUCfd41Srgw527y83/MkDriQAZ2K43E0GZj72C6f8+AfnGW3190yIKHbcu1O65IZSPS/LA4B51zTKx+14dpEEw1gms0yXhVEn9WKIkQf+nO/NyleDD6irsJzue+8CGCvzmWahQigAAAAASUVORK5CYII='); }
#gdf > .favnote.arrow { background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABnUlEQVR4Ac2QA6weURCFt7bduHZc27YV1bZt+9m2bdu2bRvn7Tz8ZthJvsXdPd+ducz/UeF2/V6zmMnIaiFBqE0/i7YqdbSU/URz6Xc0l3xBY9F71OU9Q3X2PVRm3ASR4L8H9C/LGj5BsFU/y7YKBTQVvkBjwTM05D9Ffd5j1GTfR3naLRQnXUFhwkVEuG8BGt1A/7Os5QgCLfpZtVUoobnopUSJl+UyDub/+nlxBH6m/WzaK1XQWvKaJFI7oXEowxF4G/Wz66hSQ1vpG5kkJKAMR+Cu38+ho1oD7WXvZJLQwVKGI3DR6efUWaOJjvL3UiUfnF1hF2YAynAEDpr9XFCjzQo+SJWc0Q/DWYMIvFE9HccR2Kr2c0OtDjorPgpJXlrY4JiqD4GjhIo3lAqAjV9saxa/jz7NUBn/ZnxQbwWSUCfd41Srgw527y83/MkDriQAZ2K43E0GZj72C6f8+AfnGW3190yIKHbcu1O65IZSPS/LA4B51zTKx+14dpEEw1gms0yXhVEn9WKIkQf+nO/NyleDD6irsJzue+8CGCvzmWahQigAAAAASUVORK5CYII='); }
#gdf > .favnote.pencil { background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABwElEQVR4Ac2QA4yYMQCF23nRfEMwe4sz27Zt297Ztm3btm3btt/+XnJmvJfU/b6C/B+JdKB8XLGYYNlFhibcjlp11GiirUIGreVSaC0TR3OJEBoKfqE29xOqs96ClaTA02B7ubJ7kCDUhlp3VCmhpfgPmot+oanwJxoLvqMu9zMqM96hNOUFipOeIsrzMNDsAbafK3v6BMFW1KajSgWtJX/HlPhYb+0rlorUp08QYE7tOqvV0F7GxyTj3oQ9hzF9Al8T6tBVo4GOcv4JSUqtriJlAy0NpnQfYfE0pE5dtVrorBAcV5IS+gqu4hcBXl7YUepHWNz0qEt3nTa6KoXGlBTF34KF3kO0tLTg64nZOTqEHCEsTtrUDXW6nEB4VElJ4h0EWq/m+t8hLXwZCrzTgvv+wF6deqBeD91VIiNKypLvI8hmDYNhpboM6eEvwZg+gakc8UOjDZiE3aTnObWaYB9bkf4OwbabGQwb9TXIinyD9kplMKaXn/vlMdHVFCJhQ4u2IImzUKC1DFb+S+tVeElq7xpjGMsVMpMrPFxZMrQIPKRSaEyD7Hca9PAiuTBknaeHHSd4dpZafL1Ld4+24R9mFfDtXW/67AAAAABJRU5ErkJggg=='); }
#gdf > .favnote.pencil { background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABwElEQVR4Ac2QA4yYMQCF23nRfEMwe4sz27Zt297Ztm3btm3btt/+XnJmvJfU/b6C/B+JdKB8XLGYYNlFhibcjlp11GiirUIGreVSaC0TR3OJEBoKfqE29xOqs96ClaTA02B7ubJ7kCDUhlp3VCmhpfgPmot+oanwJxoLvqMu9zMqM96hNOUFipOeIsrzMNDsAbafK3v6BMFW1KajSgWtJX/HlPhYb+0rlorUp08QYE7tOqvV0F7GxyTj3oQ9hzF9Al8T6tBVo4GOcv4JSUqtriJlAy0NpnQfYfE0pE5dtVrorBAcV5IS+gqu4hcBXl7YUepHWNz0qEt3nTa6KoXGlBTF34KF3kO0tLTg64nZOTqEHCEsTtrUDXW6nEB4VElJ4h0EWq/m+t8hLXwZCrzTgvv+wF6deqBeD91VIiNKypLvI8hmDYNhpboM6eEvwZg+gakc8UOjDZiE3aTnObWaYB9bkf4OwbabGQwb9TXIinyD9kplMKaXn/vlMdHVFCJhQ4u2IImzUKC1DFb+S+tVeElq7xpjGMsVMpMrPFxZMrQIPKRSaEyD7Hca9PAiuTBknaeHHSd4dpZafL1Ld4+24R9mFfDtXW/67AAAAABJRU5ErkJggg=='); }
#gdf > .favnote.exclamation { background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAB5ElEQVR4AcWQA4yfMQBHXzvbtm3b4RzNXow5mIPZWzTbtm3btre/1a/dXXN2uF9St6+v5b9HANw8IKYDNclYFjfuZi4mAlzfJ3Y1aLuit1YejNFgHLSO4KgAjhNEOxEAvnx5je/Xwd3AoqY9zAUACaA1Ah1CR/7Y4kRcaOVFOyFURBEORwgGg7Y06XK8t9aMvrpHtAXIHAdAIoSIYWrbZspkl22UCuN2uzl7dBLQtNevz9cLAB3sDsdBCiGRUqK1ThVSo0YjtHbInj07j9R1N9idcQBrIKVto0pcayEB33P+fD9J0PuC2DNxT1DRA3vA3pzUxPaDvs+UrT2eD48W233RZ5IYCGxJwcTneUuOfLXIlj0/uQrUIhT4FmcgYw2E7aYEAdfvF+QtXJ++Q7aTt2AtXH9eRgMyEWegkMQYJIV4XO/IlLUIRrnYsWMHfs9nNNkRgkJxf+APmKzIvIgsIIzBoMFoRFT5EfVxeYpW4fOf6xw6OJ4fwRtkypEVbSgxsJe9koITRrKganlqkCTZsoncJUsXKFupQf3cjnJRqdYtXj1qBAhe3Xv6bdUm32AB5ADyWJskWTlTLGzVrmKngkWyFsIYchfqhffXHgB+//T+vH/r0yFBGlk/l2Va05BUIiW3/wHmcuCUyEztWwAAAABJRU5ErkJggg=='); }
#gdf > .favnote.exclamation { background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAB5ElEQVR4AcWQA4yfMQBHXzvbtm3b4RzNXow5mIPZWzTbtm3btre/1a/dXXN2uF9St6+v5b9HANw8IKYDNclYFjfuZi4mAlzfJ3Y1aLuit1YejNFgHLSO4KgAjhNEOxEAvnx5je/Xwd3AoqY9zAUACaA1Ah1CR/7Y4kRcaOVFOyFURBEORwgGg7Y06XK8t9aMvrpHtAXIHAdAIoSIYWrbZspkl22UCuN2uzl7dBLQtNevz9cLAB3sDsdBCiGRUqK1ThVSo0YjtHbInj07j9R1N9idcQBrIKVto0pcayEB33P+fD9J0PuC2DNxT1DRA3vA3pzUxPaDvs+UrT2eD48W233RZ5IYCGxJwcTneUuOfLXIlj0/uQrUIhT4FmcgYw2E7aYEAdfvF+QtXJ++Q7aTt2AtXH9eRgMyEWegkMQYJIV4XO/IlLUIRrnYsWMHfs9nNNkRgkJxf+APmKzIvIgsIIzBoMFoRFT5EfVxeYpW4fOf6xw6OJ4fwRtkypEVbSgxsJe9koITRrKganlqkCTZsoncJUsXKFupQf3cjnJRqdYtXj1qBAhe3Xv6bdUm32AB5ADyWJskWTlTLGzVrmKngkWyFsIYchfqhffXHgB+//T+vH/r0yFBGlk/l2Va05BUIiW3/wHmcuCUyEztWwAAAABJRU5ErkJggg=='); }


#gdf > .favnote:after { width: 70px; content: "See your note"; }
#gdf > .favnote:after { width: 70px; content: "See your note"; }
#gdf > .favnote.plus:after { width: 55px; content: "Add a note"; }
#gdf > .favnote.plus:after { width: 55px; content: "Add a note"; }
#gdf > .favnote.arrow:after { width: 70px; content: "Save the note"; }
#gdf > .favnote.arrow:after { width: 70px; content: "Save the note"; }
#gdf > .favnote.pencil:after { width: 70px; content: "Edit your note"; }
#gdf > .favnote.pencil:after { width: 70px; content: "Edit your note"; }
#gdf > .favnote.exclamation:after { width: 300px; height: 60px !important; white-space: normal; content: "Note failed to load. Click to retry. WARNING: Changing favourite category while the note is not loaded will remove existing notes!"; }
#gdf > .favnote.exclamation:after { width: 300px; height: 60px !important; white-space: normal; content: "Note failed to load. Click to retry. WARNING: Changing favourite category while the note is not loaded will remove existing notes!"; }


#gdf > .favnote + .editor {
#gdf > .favnote + .editor {
position: absolute;
position: absolute;
height: 18px;
height: 18px;
background: ${color.bg_light} !important;
background: ${color.bg_light} !important;
padding: 10px;
padding: 10px;
top: -1px;
top: -1px;
left: 132px;
left: 132px;
z-index: 10;
z-index: 10;
border: 1px solid ${color.border};
border: 1px solid ${color.border};
visibility: hidden;
visibility: hidden;
}
}


#gdf > .favnote + .editor > input {
#gdf > .favnote + .editor > input {
margin: 0 0 0 30px;
margin: 0 0 0 30px;
height: 12px;
height: 12px;
}
}


#gdf > .favnote + .editor > input.notinput {
#gdf > .favnote + .editor > input.notinput {
border-color: transparent;
border-color: transparent;
background: none !important;
background: none !important;
color: inherit !important;
color: inherit !important;
cursor: default !important;
cursor: default !important;
outline: none !important;
outline: none !important;
color: transparent !important;
color: transparent !important;
text-shadow: 0 0 0 ${color.border};
text-shadow: 0 0 0 ${color.border};
}
}


#gdf > .favnote + .editor.show { visibility: visible; }
#gdf > .favnote + .editor.show { visibility: visible; }


#gdf.hover .fav {
#gdf.hover .fav {
position: relative;
position: relative;
}
}


#gdf .hotkey-hint {
#gdf .hotkey-hint {
position: absolute;
position: absolute;
top: 4px;
top: 4px;
right: 0;
right: 0;
box-sizing: border-box;
box-sizing: border-box;
padding: 0 1px 0 2px;
padding: 0 1px 0 2px;
border: 1px solid #888;
border: 1px solid #888;
border-radius: 2px;
border-radius: 2px;
background: #eee;
background: #eee;
color: #666 !important;
color: #666 !important;
font-family: monospace;
font-family: monospace;
font-size: 13px;
font-size: 13px;
box-shadow: -3px 0 2px 2px ${color.bg_light};
box-shadow: -3px 0 2px 2px ${color.bg_light};
visibility: hidden;
visibility: hidden;
}
}


#gdf.hover .fav:hover .hotkey-hint {
#gdf.hover .fav:hover .hotkey-hint {
box-shadow: -3px 0 2px 2px ${color.bg};
box-shadow: -3px 0 2px 2px ${color.bg};
}
}


#gdf.hover .hotkey-hint {
#gdf.hover .hotkey-hint {
visibility: visible;
visibility: visible;
}
}


`;
`;


/* ========================================================================= *\
/* ========================================================================= *\
* * UTILITY FUNCTIONS
* * UTILITY FUNCTIONS
\* ========================================================================= */
\* ========================================================================= */
// Debug msg
// Debug msg
function dlog(msg) {
function dlog(...msg) {
if ( config.debug ) {
if ( config.debug ) {
console.log(`"EHGQF: ${msg}`);
console.log("EHGQF:", ...msg);
}
}
}
}


// Get the actual/current favourite category of the current gallery
// Get the actual/current favourite category of the current gallery
function getPageFavId() {
function getPageFavId() {
let idElement = document.querySelector("#fav .i");
let idElement = document.querySelector("#fav .i");
if ( !idElement ) return 10;
if ( !idElement ) return 10;


return (idElement.style.backgroundPositionY.match(/\d+/)[0] - 2)/19;
return (idElement.style.backgroundPositionY.match(/\d+/)[0] - 2)/19;
}
}




/* ========================================================================= *\
/* ========================================================================= *\
* * UI INJECTIONS
* * UI INJECTIONS
\* ========================================================================= */
\* ========================================================================= */
// Inject CSS
// Inject CSS
function injectStylesheet() {
function injectStylesheet() {
dlog("Injecting stylesheet");
dlog("Injecting stylesheet");
var stylesheetEl = document.createElement("style");
var stylesheetEl = document.createElement("style");
stylesheetEl.innerHTML = stylesheet;
stylesheetEl.innerHTML = stylesheet;
document.body.appendChild(stylesheetEl);
document.body.appendChild(stylesheetEl);
}
}


// Build and inject FavNote UI
// Build and inject FavNote UI
function injectFavnoteElements() {
function injectFavnoteElements() {
dlog("Injecting Favnote UI elements");
dlog("Injecting Favnote UI elements");


// Fetch the FavID of the current gallery
// Fetch the FavID of the current gallery
var curFavID = getPageFavId();
var curFavID = getPageFavId();


// Fetch favnotes if current gallery was already in a fav category
// Fetch favnotes if current gallery was already in a fav category
if ( curFavID != 10 ) {
if ( curFavID != 10 ) {
fetchFavouriteNotes( favnote => {
fetchFavouriteNotes( favnote => {


// Determine icon type
// Determine icon type
var favnoteStatus = "";
var favnoteStatus = "";
if ( favnote === false ) favnoteStatus = "exclamation";
if ( favnote === false ) favnoteStatus = "exclamation";
if ( favnote === "" ) favnoteStatus = "plus";
if ( favnote === "" ) favnoteStatus = "plus";


// Build elements for Favnotes
// Build elements for Favnotes
var favnoteEl = `
var favnoteEl = `
<div class='favnote ${favnoteStatus}'></div>
<div class='favnote ${favnoteStatus}'></div>
<div class="editor">
<div class="editor">
<input type="text" size="${config.editor_size}" class="stdinput" value="${favnote}">
<input type="text" size="${config.editor_size}" class="stdinput" value="${favnote}">
</div>
</div>
`;
`;


// Inject
// Inject
var gdf = document.getElementById("gdf");
var gdf = document.getElementById("gdf");
gdf.insertAdjacentHTML("beforeend", favnoteEl);
gdf.insertAdjacentHTML("beforeend", favnoteEl);


// Add event listeners
// Add event listeners
document.querySelector("#gdf > .favnote").addEventListener("click", favnoteClick);
document.querySelector("#gdf > .favnote").addEventListener("click", favnoteClick);


dlog("Successfully injected Favnote UI");
dlog("Successfully injected Favnote UI");
return;
return;
});
});
}
}
dlog("FavID = 10: No notes to inject!");
dlog("FavID = 10: No notes to inject!");
}
}


// Build & Inject QF UI
// Build & Inject QF UI
function injectQFElements() {
function injectQFElements() {
var i;
var i;
dlog("Injecting Quick Fav UI elements");
dlog("Injecting Quick Fav UI elements");


// Fetch the FavID of the current gallery
// Fetch the FavID of the current gallery
var curFavID = getPageFavId();
var curFavID = getPageFavId();


// Fetch the Labels of the 10 Fav items
// Fetch the Labels of the 10 Fav items
var favLabels = [];
var favLabels = [];
for (i=0; i<10; i++) {
for (i=0; i<10; i++) {
var label = localStorage.getItem(`EHGQF-fav${i}`);
var label = localStorage.getItem(`EHGQF-fav${i}`);
if ( !label ) label = `Favorites ${i+1}`;
if ( !label ) label = `Favorites ${i+1}`;
favLabels.push(label);
favLabels.push(label);
}
}


// Build fav item elements
// Build fav item elements
var favEl = [];
var favEl = [];
for (i=0; i<10; i++) {
for (i=0; i<10; i++) {
var offset = 2 + (i*19);
var offset = 2 + (i*19);
var el = `
var el = `
<div qfid='${i}' class='fav'>
<div qfid='${i}' class='fav'>
<div class="i" style="background-image:url(https://ehgt.org/g/fav.png); background-position:0px -${offset}px;"></div>
<div class="i" style="background-image:url(https://ehgt.org/g/fav.png); background-position:0px -${offset}px;"></div>
&nbsp; <a id="favoritelink" href="#">${favLabels[i]}</a>
&nbsp; <a id="favoritelink" href="#">${favLabels[i]}</a>
<div class="hotkey-hint">${i}</div>
<div class="hotkey-hint">${i}</div>
</div>
</div>
`;
`;
favEl.push(el);
favEl.push(el);
}
}


// Add the `remove favorites` fav item
// Add the `remove favorites` fav item
favEl.push(`
favEl.push(`
<div qfid='favdel' class='fav'>
<div qfid='favdel' class='fav'>
<a id="favoritelink" href="#">Remove from Favorites</a>
<a id="favoritelink" href="#">Remove from Favorites</a>
<div class="hotkey-hint">-</div>
<div class="hotkey-hint">-</div>
</div>
</div>
`);
`);


// Build top list
// Build top list
var qfTopElContent = "";
var qfTopElContent = "";
for (i=0; i<curFavID; i++) { qfTopElContent += favEl[i]; }
for (i=0; i<curFavID; i++) { qfTopElContent += favEl[i]; }
var qfTopEl = `<div class='qf-top'>${qfTopElContent}</div>`;
var qfTopEl = `<div class='qf-top'>${qfTopElContent}</div>`;


// Build bottom list
// Build bottom list
var qfBotElContent = "";
var qfBotElContent = "";
for (i=curFavID+1; i<favEl.length; i++) { qfBotElContent += favEl[i]; }
for (i=curFavID+1; i<favEl.length; i++) { qfBotElContent += favEl[i]; }
var qfBotEl = `<div class='qf-bot'>${qfBotElContent}</div>`;
var qfBotEl = `<div class='qf-bot'>${qfBotElContent}</div>`;


// Inject Elements! Finally
// Inject Elements! Finally
var gdf = document.getElementById("gdf");
var gdf = document.getElementById("gdf");
gdf.insertAdjacentHTML("beforeend", qfTopEl);
gdf.insertAdjacentHTML("beforeend", qfTopEl);
gdf.insertAdjacentHTML("beforeend", qfBotEl);
gdf.insertAdjacentHTML("beforeend", qfBotEl);


// Add Event Listeners
// Add Event Listeners
var favDOMEl = document.querySelectorAll("#gdf .fav");
var favDOMEl = document.querySelectorAll("#gdf .fav");
for(i=0; i<favDOMEl.length; i++) {
for(i=0; i<favDOMEl.length; i++) {
favDOMEl[i].addEventListener("click", quickFavourite);
favDOMEl[i].addEventListener("click", quickFavourite);
}
}


// Disable `#gdf` click event; move it to its child element;
// Disable `#gdf` click event; move it to its child element;
gdf.children[0].onclick = gdf.onclick;
gdf.children[0].onclick = gdf.onclick;
gdf.children[1].onclick = gdf.onclick;
gdf.children[1].onclick = gdf.onclick;
gdf.onclick = "";
gdf.onclick = "";


dlog("UI Injection successful!");
dlog("UI Injection successful!");
}
}




/* ========================================================================= *\
/* ========================================================================= *\
* * QUICK FAVOURITE
* * QUICK FAVOURITE
\* ========================================================================= */
\* ========================================================================= */
// Send Favouriting XHR request to EH server
// Send Favouriting XHR request to EH server
function quickFavourite(id) {
function quickFavourite(id) {
dlog("quickFavourite() triggered!");
dlog("quickFavourite() triggered!");


// Gather and build things
// Gather and build things
let favnoteEl = document.querySelector(".favnote + .editor > input");
let favnoteEl = document.querySelector(".favnote + .editor > input");
let favnote = (favnoteEl) ? favnoteEl.value : "";
let favnote = (favnoteEl) ? favnoteEl.value : "";
let favID;
let favID;
try { favID = this.attributes.qfid.value; } catch(e) {
try { favID = this.attributes.qfid.value; } catch(e) {
favID = id;
favID = id;
}
}
let galID = location.pathname.match(/^\/\w\/(\d+)\//)[1];
let galID = location.pathname.match(/^\/\w\/(\d+)\//)[1];
let token = location.pathname.match(/\/(\w+)\/$/)[1];
let token = location.pathname.match(/\/(\w+)\/$/)[1];
let prot = location.protocol;
let prot = location.protocol;
let host = location.host;
let host = location.host;
let url = `${prot}//${host}/gallerypopups.php?gid=${galID}&t=${token}&act=addfav`;
let url = `${prot}//${host}/gallerypopups.php?gid=${galID}&t=${token}&act=addfav`;
let dat = `apply=Add to Favorites&favcat=${favID}&favnote=${favnote}&update=1`;
let dat = `apply=Add to Favorites&favcat=${favID}&favnote=${favnote}&update=1`;


// Prepare to send XHR
let xhr = new XMLHttpRequest();
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");

// Remove Quick Favourite Elements to prevent sending multiple XHR
// Remove Quick Favourite Elements to prevent sending multiple XHR
document.querySelector(".qf-top").remove();
document.querySelector(".qf-top").remove();
document.querySelector(".qf-bot").remove();
document.querySelector(".qf-bot").remove();
if ( favnoteEl ) document.querySelector(".favnote").remove();
if ( favnoteEl ) document.querySelector(".favnote").remove();
if ( favnoteEl ) document.querySelector(".editor").remove();
if ( favnoteEl ) document.querySelector(".editor").remove();


// Send XHR
// Send XHR
xhr.send(dat);
GM.xmlHttpRequest({

method: "POST",
// Update UI if request was successful
url: url,
xhr.onload = function() {
data: dat,
if (xhr.status == 200) {
headers: {
updateCurrentFav(favID); // Update #gdf
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"
},
onload: function(response) {
if (response.status == 200) {
updateCurrentFav(favID); // Update #gdf
} else {
} else {
dlog("Error occurred! Favorite was not updated!");
dlog("Error occurred! Favorite was not updated!");
alert("Error occurred! Favorite was not updated!");
alert("Error occurred! Favorite was not updated!");
}
}


injectQFElements(); // Reinject Quick Favourite UI
injectQFElements(); // Reinject Quick Favourite UI
injectFavnoteElements(); // and Favnote UI
injectFavnoteElements(); // and Favnote UI
disableHotkeys();
disableHotkeys();
dlog("quickFavourite() done!"); // Done!
dlog("quickFavourite() done!"); // Done!
};
},
});
}
}


// Update the current/actual Favourite Category of the current Gallery
// Update the current/actual Favourite Category of the current Gallery
function updateCurrentFav(favID) {
function updateCurrentFav(favID) {
dlog("Updating current fav with favID "+favID);
dlog("Updating current fav with favID "+favID);


// If id is not specified, refresh
// If id is not specified, refresh
if ( typeof favID == "undefined" ) {
if ( typeof favID == "undefined" ) {
favID = getPageFavId();
favID = getPageFavId();
dlog("FavID set to " + favID);
dlog("FavID set to " + favID);
}
}


var el;
var el;


if (favID == "favdel" || favID === 10) {
if (favID == "favdel" || favID === 10) {
el = `
el = `
<div style="float:left">
<div style="float:left">
&nbsp; <a onclick="return false" href="#" id="favoritelink"><img src="https://ehgt.org/g/mr.gif"> Add to Favorites</a>
&nbsp; <a onclick="return false" href="#" id="favoritelink"><img src="https://ehgt.org/g/mr.gif"> Add to Favorites</a>
<div class="hotkey-hint"></div>
<div class="hotkey-hint"></div>
</div>
</div>
`;
`;
} else {
} else {
// Fetch the Labels of the 10 Fav items
// Fetch the Labels of the 10 Fav items
var favLabels = [];
var favLabels = [];
for (let i=0; i<10; i++) {
for (let i=0; i<10; i++) {
var label = localStorage.getItem(`EHGQF-fav${i}`);
var label = localStorage.getItem(`EHGQF-fav${i}`);
if ( !label ) label = `Favorites ${i}`;
if ( !label ) label = `Favorites ${i}`;
favLabels.push(label);
favLabels.push(label);
}
}


// Calculate bg offset
// Calculate bg offset
var offset = 2 + (favID*19);
var offset = 2 + (favID*19);


// Build
// Build
el = `
el = `
<div id="fav" style="float:left; cursor:pointer">
<div id="fav" style="float:left; cursor:pointer">
<div title="Read Later" style="background-image:url(https://ehgt.org/g/fav.png); background-position:0px -${offset}px;" class="i"></div>
<div title="Read Later" style="background-image:url(https://ehgt.org/g/fav.png); background-position:0px -${offset}px;" class="i"></div>
</div>
</div>
<div style="float:left">&nbsp;
<div style="float:left">&nbsp;
<a onclick="return false" href="#" id="favoritelink">${favLabels[favID]}</a>
<a onclick="return false" href="#" id="favoritelink">${favLabels[favID]}</a>
</div>
</div>
`;
`;
}
}


document.getElementById("gdf").innerHTML = el;
document.getElementById("gdf").innerHTML = el;
}
}


/* ========================================================================= *\
/* ========================================================================= *\
* * FAVOURITE NOTES
* * FAVOURITE NOTES
\* ========================================================================= */
\* ========================================================================= */
// Get Favourite Notes remotely from the popup
// Get Favourite Notes remotely from the popup
function fetchFavouriteNotes(cb) {
function fetchFavouriteNotes(cb) {
dlog("Beginning to check favnotes");
dlog("Beginning to check favnotes");


// Send XHR to Favourite Page
// Send XHR to Favourite Page
var galID = location.pathname.match(/^\/\w\/(\d+)\//)[1];
var galID = location.pathname.match(/^\/\w\/(\d+)\//)[1];
var token = location.pathname.match(/\/(\w+)\/$/)[1];
var token = location.pathname.match(/\/(\w+)\/$/)[1];
var prot = location.protocol;
var prot = location.protocol;
var host = location.host;
var host = location.host;
var url = `${prot}//${host}/gallerypopups.php?gid=${galID}&t=${token}&act=addfav`;
var url = `${prot}//${host}/gallerypopups.php?gid=${galID}&t=${token}&act=addfav`;


var xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
GM.xmlHttpRequest({
xhr.timeout = config.timeout;
method: "GET",
xhr.responseType = "document";
url: url,
xhr.send();
timeout: config.timeout,

onload: function(response) {
// And grab the favnotes
if (response.status === 200) {
xhr.onload = function() {
const responseXML = new DOMParser().parseFromString(response.responseText, "text/xml");
if ( xhr.status == 200 ) {
var favnoteEl = responseXML.querySelector("textarea[name='favnote']");
// grab it!
dlog("Favnotes successfully found");
var data = xhr.response;
cb(favnoteEl.value); // Fire callback function
var favnoteEl = data.querySelector("textarea[name='favnote']");
dlog("Favnotes successfully found");
cb(favnoteEl.value); // Fire callback function
} else {
} else {
dlog("XHR failed; notes not found");
dlog("XHR failed; notes not found");
return false;
}
}
};
},

ontimeout: function() {
xhr.timeout = function() {
dlog("XHR timed out; notes not found");
dlog("XHR timed out; notes not found");
return false;
return false;
};
},

});
}
}


// Update favnote icon status
// Update favnote icon status
function updateFavnoteIcon(status) {
function updateFavnoteIcon(status) {
dlog(`Updating favnote icon to ${status}`);
dlog(`Updating favnote icon to ${status}`);
var favnoteEl = document.querySelector("#gdf > .favnote");
var favnoteEl = document.querySelector("#gdf > .favnote");


// Clear all classes but .favnote
// Clear all classes but .favnote
favnoteEl.className = "favnote";
favnoteEl.className = "favnote";


// Add status
// Add status
favnoteEl.classList.add(status);
favnoteEl.classList.add(status);
}
}


// FavNote click event handler
// FavNote click event handler
function favnoteClick() {
function favnoteClick() {
var favnoteEl = this;
var favnoteEl = this;
var editorEl = document.querySelector("#gdf > .favnote + .editor");
var editorEl = document.querySelector("#gdf > .favnote + .editor");
var inputEl = document.querySelector("#gdf > .favnote + .editor > input");
var inputEl = document.querySelector("#gdf > .favnote + .editor > input");


// Determine mode
// Determine mode
var mode;
var mode;
if ( favnoteEl.classList.length === 1 ) mode = "show";
if ( favnoteEl.classList.length === 1 ) mode = "show";
else if ( favnoteEl.classList.contains("arrow") ) mode = "save";
else if ( favnoteEl.classList.contains("arrow") ) mode = "save";
else if ( favnoteEl.classList.contains("exclamation") ) mode = "reload";
else if ( favnoteEl.classList.contains("exclamation") ) mode = "reload";
else mode = "edit";
else mode = "edit";


// Behave accordingly
// Behave accordingly
switch(mode) {
switch(mode) {
case "show":
case "show":
updateFavnoteIcon("pencil"); // marks the next action to edit
updateFavnoteIcon("pencil"); // marks the next action to edit
editorEl.classList.add("show");
editorEl.classList.add("show");
inputEl.classList.add("notinput");
inputEl.classList.add("notinput");
break;
break;
case "edit":
case "edit":
updateFavnoteIcon("arrow"); // marks the next action to save
updateFavnoteIcon("arrow"); // marks the next action to save
editorEl.classList.add("show");
editorEl.classList.add("show");
inputEl.classList.remove("notinput");
inputEl.classList.remove("notinput");
break;
break;
case "save":
case "save":
var favID = getPageFavId();
var favID = getPageFavId();
quickFavourite(favID);
quickFavourite(favID);
break;
break;
case "reload":
case "reload":
// an error occurred, attempt to reload favnotes
// an error occurred, attempt to reload favnotes
document.querySelector(".favnote").remove();
document.querySelector(".favnote").remove();
document.querySelector(".editor").remove();
document.querySelector(".editor").remove();
injectFavnoteElements();
injectFavnoteElements();
break;
break;
default:
default:
dlog("What is happening?");
dlog("What is happening?");
alert("A really strange error occurred. This part of code should be reached.");
alert("A really strange error occurred. This part of code should be reached.");
return;
return;
}
}
}
}




/* ========================================================================= *\
/* ========================================================================= *\
* * FAVOURITE HOTKEYS
* * FAVOURITE HOTKEYS
\* ========================================================================= */
\* ========================================================================= */
// Adds keypress event listener
// Adds keypress event listener
function injectHotkeyListener() {
function injectHotkeyListener() {
document.addEventListener("keypress", hotkeyHandler);
document.addEventListener("keypress", hotkeyHandler);
dlog("Listening to keypress events now");
dlog("Listening to keypress events now");
}
}


// Handles keypresses
// Handles keypresses
function hotkeyHandler(e) {
function hotkeyHandler(e) {
let key = e.which;
let key = e.which;
let char = String.fromCharCode(key);
let char = String.fromCharCode(key);
if (hotkeyInit) {
if (hotkeyInit) {
if (e.keyCode == 27) {
if (e.keyCode == 27) {
return;
return;
}
}


// 0-9 and "-"
// 0-9 and "-"
let favID;
let favID;
switch(char) {
switch(char) {
case("0"):
case("0"):
favID = 0;
favID = 0;
break;
break;
case("1"):
case("1"):
favID = 1;
favID = 1;
break;
break;
case("2"):
case("2"):
favID = 2;
favID = 2;
break;
break;
case("3"):
case("3"):
favID = 3;
favID = 3;
break;
break;
case("4"):
case("4"):
favID = 4;
favID = 4;
break;
break;
case("5"):
case("5"):
favID = 5;
favID = 5;
break;
break;
case("6"):
case("6"):
favID = 6;
favID = 6;
break;
break;
case("7"):
case("7"):
favID = 7;
favID = 7;
break;
break;
case("8"):
case("8"):
favID = 8;
favID = 8;
break;
break;
case("9"):
case("9"):
favID = 9;
favID = 9;
break;
break;
case("-"):
case("-"):
favID = "favdel";
favID = "favdel";
break;
break;
default:
default:
disableHotkeys();
disableHotkeys();
break;
break;
}
}
if (typeof favID != "undefined") quickFavourite(favID);
if (typeof favID != "undefined") quickFavourite(favID);
} else {
} else {
if (char == "F") enableHotkeys();
if (char == "F") enableHotkeys();
}
}
}
}


function enableHotkeys() {
function enableHotkeys() {
hotkeyInit = true;
hotkeyInit = true;
if(config.cheatsheet) showCheatSheet();
if(config.cheatsheet) showCheatSheet();
dlog("Entering active hotkey favouriting mode");
dlog("Entering active hotkey favouriting mode");
}
}


function disableHotkeys() {
function disableHotkeys() {
if(config.cheatsheet) hideCheatSheet();
if(config.cheatsheet) hideCheatSheet();
hotkeyInit = false;
hotkeyInit = false;
dlog("Quitting active hotkey favouriting mode");
dlog("Quitting active hotkey favouriting mode");
}
}


function showCheatSheet() {
function showCheatSheet() {
dlog("Showing Cheat Sheet");
dlog("Showing Cheat Sheet");
document.getElementById("gdf").classList.add("hover");
document.getElementById("gdf").classList.add("hover");
}
}


function hideCheatSheet() {
function hideCheatSheet() {
dlog("Hiding Cheat Sheet");
dlog("Hiding Cheat Sheet");
document.getElementById("gdf").classList.remove("hover");
document.getElementById("gdf").classList.remove("hover");
}
}




/* ========================================================================= *\
/* ========================================================================= *\
* * CORE LOGICS
* * CORE LOGICS
\* ========================================================================= */
\* ========================================================================= */
function checkSyncNecessity() {
function checkSyncNecessity() {
// >1w = stale
// >1w = stale
let currentTime = new Date().getTime();
let currentTime = new Date().getTime();
let lastSyncTime = localStorage.getItem("EHGQF-lastSyncTime");
let lastSyncTime = localStorage.getItem("EHGQF-lastSyncTime");
let timeDelta = currentTime - lastSyncTime;
let timeDelta = currentTime - lastSyncTime;
if ( timeDelta > 1000*60*60*24*7 ) return true;
if ( timeDelta > 1000*60*60*24*7 ) return true;


// setup
// setup
let x = localStorage.getItem("EHGQF-setup");
let x = localStorage.getItem("EHGQF-setup");
if (typeof x == "undefined") return true;
if (typeof x == "undefined") return true;


// constant page check
// constant page check
let labelId = getPageFavId();
let labelId = getPageFavId();
if ( labelId == 10 ) return false; // can't check if page isn't favourited yet
if ( labelId == 10 ) return false; // can't check if page isn't favourited yet


let pageLabel = document.querySelector("#favoritelink").textContent;
let pageLabel = document.querySelector("#favoritelink").textContent;
let storedLabel = localStorage.getItem(`EHGQF-fav${labelId}`);
let storedLabel = localStorage.getItem(`EHGQF-fav${labelId}`);
if ( pageLabel != storedLabel ) return true;
if ( pageLabel != storedLabel ) return true;


dlog("No reason found to sync favourite labels");
dlog("No reason found to sync favourite labels");
return false;
return false;
}
}


function syncFavouriteLabels() {
function syncFavouriteLabels() {
dlog("Fetching fresh Favourite Labels!");
dlog("Fetching fresh Favourite Labels!");


// Send XHR to Favourite Page
// Send XHR to Favourite Page
var galID = location.pathname.match(/^\/\w\/(\d+)\//)[1];
var galID = location.pathname.match(/^\/\w\/(\d+)\//)[1];
var token = location.pathname.match(/\/(\w+)\/$/)[1];
var token = location.pathname.match(/\/(\w+)\/$/)[1];
var prot = location.protocol;
var prot = location.protocol;
var host = location.host;
var host = location.host;
var url = `${prot}//${host}/gallerypopups.php?gid=${galID}&t=${token}&act=addfav`;
var url = `${prot}//${host}/gallerypopups.php?gid=${galID}&t=${token}&act=addfav`;


var xhr = new XMLHttpRequest();
GM.xmlHttpRequest({
xhr.open("GET", url, true);
method: "GET",
xhr.responseType = "document";
url: url,
xhr.send();
onload: function(response) {

const responseXML = new DOMParser().parseFromString(response.responseText, "text/xml");
// And grab the favnotes
xhr.onreadystatechange = function() {
for(let i=0; i<=9; i++) {
if ( xhr.readyState == 4 && xhr.status == 200 ) {
let label = responseXML.querySelector(`div + div + div[onclick*='fav${i}']`).textContent;
let data = xhr.response;
localStorage.setItem(`EHGQF-fav${i}`, label);
for(let i=0; i<=9; i++) {
let label = data.querySelector(`div + div + div[onclick*='fav${i}']`).textContent;
localStorage.setItem(`EHGQF-fav${i}`, label);
}
dlog("Favourite Labels Updated!");
let time = new Date().getTime();
localStorage.setItem("EHGQF-setup", 1);
localStorage.setItem("EHGQF-lastSyncTime", time);
updateCurrentFav();
injectQFElements();
}
}
};
dlog("Favourite Labels Updated!");
let time = new Date().getTime();
localStorage.setItem("EHGQF-setup", 1);
localStorage.setItem("EHGQF-lastSyncTime", time);
updateCurrentFav();
injectQFElements();
}
});
}
}


function init() {
function init() {
dlog("Initialization start!");
dlog("Initialization start!");
if ( checkSyncNecessity() ) syncFavouriteLabels();
if ( checkSyncNecessity() ) syncFavouriteLabels();
injectStylesheet();
injectStylesheet();
injectQFElements();
injectQFElements();
injectFavnoteElements();
injectFavnoteElements();
if (config.hotkeys) injectHotkeyListener();
if (config.hotkeys) injectHotkeyListener();


dlog("Initialization finished!");
dlog("Initialization finished!");
}
}


init();
init();