Untitled diff

Created Diff never expires
5 removals
Lines
Total
Removed
Words
Total
Removed
To continue using this feature, upgrade to
Diffchecker logo
Diffchecker Pro
570 lines
137 additions
Lines
Total
Added
Words
Total
Added
To continue using this feature, upgrade to
Diffchecker logo
Diffchecker Pro
700 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.0.3
// @version v2.1.0
// @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 none
// ==/UserScript==
// ==/UserScript==


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



// Config
// Config
const config = {
const config = {
'debug': false,
'debug': false,
'timeout': 5000, // XHR Timelimit in milliseconds
'timeout': 5000, // XHR Timelimit in milliseconds
'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
'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;


// 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};
left: -2px !important;
top: -2px !important;
}
}


#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-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 {
position: relative;
}

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

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

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

`;
`;


// Debug msg
// Debug msg
function dlog(msg) {
function dlog(msg) {
if ( config.debug ) {
if ( config.debug ) {
console.log(`"EHGQF: ${msg}`);
console.log(`"EHGQF: ${msg}`);
}
}
}
}


// Detect if page is favourite adding popup
// Detect if page is favourite adding popup
function isFavouritePopupPage() {
function isFavouritePopupPage() {
var x = location.search.match("addfav");
var x = location.search.match("addfav");
var y = location.pathname.match("gallerypopups.php");
var y = location.pathname.match("gallerypopups.php");
if ( x && y ) return true;
if ( x && y ) return true;
return false;
return false;
}
}


// Get the actual/current favourite category of the current gallery
// Get the actual/current favourite category of the current gallery
function getCurrentFavID() {
function getCurrentFavID() {
var curFavEl = document.querySelector("div[style*='g/fav.png);']");
var curFavEl = document.querySelector("div[style*='g/fav.png);']");
var curFavID;
var curFavID;
if ( curFavEl ) {
if ( curFavEl ) {
curFavID = (curFavEl.attributes.style.value.match(/background-position:0px -(\d+)px/)[1] - 2 ) / 19;
curFavID = (curFavEl.attributes.style.value.match(/background-position:0px -(\d+)px/)[1] - 2 ) / 19;
} else {
} else {
curFavID = 10; // curFavEl does not exist if gallery is not yet marked as favourite of any favs
curFavID = 10; // curFavEl does not exist if gallery is not yet marked as favourite of any favs
}
}


dlog(curFavID);
dlog(curFavID);
return curFavID;
return curFavID;
}
}


// 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();
var xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.open("GET", url, true);
xhr.timeout = config.timeout;
xhr.timeout = config.timeout;
xhr.responseType = "document";
xhr.responseType = "document";
xhr.send();
xhr.send();


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


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


}
}


// Update the locally stored favourite labels
// Update the locally stored favourite labels
function updateFavouriteLabels() {
function updateFavouriteLabels() {
dlog("Updating favourite labels");
dlog("Updating favourite labels");
var favs = document.querySelectorAll('div[style="height:25px; cursor:pointer"]');
var favs = document.querySelectorAll('div[style="height:25px; cursor:pointer"]');
for (var i=0; i<favs.length; i++) {
for (var i=0; i<favs.length; i++) {
var label = favs[i].children[2].textContent;
var label = favs[i].children[2].textContent;
localStorage.setItem(`EHGQF-fav${i}`, label);
localStorage.setItem(`EHGQF-fav${i}`, label);
dlog(`Successfully set 'EHGQF-fav${i} to ${label}`);
dlog(`Successfully set 'EHGQF-fav${i} to ${label}`);
}
}
}
}


// 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');
dlog('Updating current fav');
var el;
var el;


if (favID == 'favdel') {
if (favID == 'favdel') {
el = `
el = `
<div style="float:left">
<div style="float:left">
&nbsp; <a onclick="return false" href="#" id="favoritelink"><img src="http://ehgt.org/g/mr.gif"> Add to Favorites</a>
&nbsp; <a onclick="return false" href="#" id="favoritelink"><img src="http://ehgt.org/g/mr.gif"> Add to Favorites</a>
<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 (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}`;
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(http://ehgt.org/g/fav.png); background-position:0px -${offset}px;" class="i"></div>
<div title="Read Later" style="background-image:url(http://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;
}
}


// 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);
}
}


// Inject Stylesheet
// Inject Stylesheet
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; this needs to be separated because it's asynchronous
// Build and inject favnote UI; this needs to be separated because it's asynchronous
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 = getCurrentFavID();
var curFavID = getCurrentFavID();


// 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(function(favnote){
fetchFavouriteNotes(function(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 ");
});
});


}
}
}
}


// Build and inject UI; also hook event listeners
// Build and inject UI; also hook event listeners
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 = getCurrentFavID();
var curFavID = getCurrentFavID();


// 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(http://ehgt.org/g/fav.png); background-position:0px -${offset}px;"></div>
<div class="i" style="background-image:url(http://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>
</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>
</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!");
}
}


// Mark gallery as favourite
// Mark gallery as favourite
function quickFavourite(id) {
function quickFavourite(id) {
dlog("quickFavourite() triggered!");
dlog("quickFavourite() triggered!");


// Gather and build things
// Gather and build things
var favnote = document.querySelector('.favnote + .editor > input').value;
var favnote = document.querySelector('.favnote + .editor > input').value;
var favID;
var favID;
try { favID = this.attributes.qfid.value; } catch(e) {
try { favID = this.attributes.qfid.value; } catch(e) {
favID = id;
favID = id;
}
}
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 dat = `apply=Add to Favorites&favcat=${favID}&favnote=${favnote}&update=1`;
var dat = `apply=Add to Favorites&favcat=${favID}&favnote=${favnote}&update=1`;


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


// 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();
document.querySelector('.favnote').remove();
document.querySelector('.favnote').remove();
document.querySelector('.editor').remove();
document.querySelector('.editor').remove();


// Send XHR
// Send XHR
xhr.send(dat);
xhr.send(dat);


// Update UI if request was successful
// Update UI if request was successful
xhr.onload = function() {
xhr.onload = function() {
if (xhr.status == 200) {
if (xhr.status == 200) {
updateCurrentFav(favID); // Update #gdf
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();
dlog("quickFavourite() done!"); // Done!
dlog("quickFavourite() done!"); // Done!
};
};


// Throw error if timeout occurred
// Throw error if timeout occurred
xhr.ontimeout = function(e) {
xhr.ontimeout = function(e) {
dlog("Timeout occurred! Favorite was not updated!");
dlog("Timeout occurred! Favorite was not updated!");
alert("Timeout occurred! Favorite was not updated!");
alert("Timeout occurred! Favorite was not updated!");
injectQFElements();
injectQFElements();
dlog("quickFavourite() timed out!");
dlog("quickFavourite() timed out!");
};
};
}
}


// What happens when favnote icon is clicked
// What happens when favnote icon is clicked
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 = getCurrentFavID();
var favID = getCurrentFavID();
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;
}
}
}
}


// Adds keypress event listener
function injectHotkeyListener() {
document.addEventListener('keypress', hotkeyHandler);
dlog("Listening to keypress events now");
}

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

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

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

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

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

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

// Main/init
// Main/init
function init() {
function init() {
if ( isFavouritePopupPage() ) {
if ( isFavouritePopupPage() ) {
// We are in favourite popup page; update labels
// We are in favourite popup page; update labels
dlog("We are in favourite popup page");
dlog("We are in favourite popup page");
updateFavouriteLabels();
updateFavouriteLabels();
} else {
} else {
// We are in gallery page; inject quick favourite ui
// We are in gallery page; inject quick favourite ui
dlog("We are in Gallery page");
dlog("We are in Gallery page");
injectStylesheet();
injectStylesheet();
injectQFElements();
injectQFElements();
injectFavnoteElements();
injectFavnoteElements();
if (config.hotkeys) injectHotkeyListener();
}
}
dlog("Initialization finished!");
dlog("Initialization finished!");
}
}


init();
init();