EH Gallery Quick Tag Voting

Adds upvote and downvote button on the left and right sides of tags in EH Gallery to allow faster and easier tag voting.

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name        EH Gallery Quick Tag Voting
// @author      FabulousCupcake
// @namespace   http://fabulous.cupcake.jp.net/
// @description Adds upvote and downvote button on the left and right sides of tags in EH Gallery to allow faster and easier tag voting.
// @include     /^https?://(ex|(g\.)?e-)hentai\.org/g/\d+?/\w{10}/?/
// @version     r5
// @grant       GM_addStyle
// @grant       unsafeWindow
// ==/UserScript==

// Config
// ----------
const config = {
    "debug"         :   false,  // Enable debugging?
    "selective_tags":   false,   // Affect only tags w/ dashed borders ( those with <100 power and still yield tagging points )
    "invert_buttons":   false,  // Invert buttons  ( [+|tag|-] by default, [-|tag|+] if inverted )
    "short_buttons":    true,   // Shorter buttons ( [+|tag|-] ,instead of [+++|---] overlay )
    "upvote_only":      false,  // Upvote only     ( [+|tag  ] )
};


// Stylesheet
// ----------
var qt_button_width_default     = (config.short_buttons ? "18px" : "35%");
var qt_button_width_elongated   = (config.short_buttons ? "35%"  : "68%");
var stylesheet = `
.gt, .gtl {
    position: relative;
}

.qtvote {
    display: block;
    width: ${qt_button_width_default};
    min-width: 18px;
    height: 18px;
    float: left;
    position: absolute;
    top: -1px;
    cursor: pointer;
    opacity: 0.2;
    transition: all 200ms ease;
    border: inherit;
    box-sizing: border-box;
}

.qtvote:hover {
    width: ${qt_button_width_elongated} !important;
    opacity: 0.9;
}

.qtvote.up    { background: rgba(0,200,0,0.6); }
.qtvote.down  { background: rgba(255,0,0,0.6); }

.qtvote.left  { left:  -1px; border-radius: 5px 0 0 5px; border-right: none; }
.qtvote.right { right: -1px; border-radius: 0 5px 5px 0; border-left:  none; }

.tup ~ .qtvote.up, .tdn ~ .qtvote.down { display: none; }
.tup ~ .qtvote.down, .tdn ~ .qtvote.up { width: ${qt_button_width_elongated}; }

.qtvote.hide { display: none; }
.tup ~ .qtvote.hide, .tdn ~ qtvote.hide { display: block; }

`;


// Utilities
// ----------
function dlog(msg) {
    if ( config.debug ) {
        console.log(`EHGQT: ${msg}`);
    }
}


// Core
// ----------

function insertElements() {
    // Fetch to-be-inserted elements
    var filter = '.gtl' + (config.selective_tags ? '' : ', .gt');
    var tags = document.querySelectorAll(filter);

    // Build insert material
    var leftvote  = ( config.invert_buttons ? "down" : "up" );
    var rightvote = ( config.invert_buttons ? "up" : "down" );
    if ( config.upvote_only ) {
        config.invert_buttons ? leftvote += ' hide' : rightvote += ' hide';
    }
    var elleft  = `<div class="qtvote left ${leftvote}"></div>`;
    var elright = `<div class="qtvote right ${rightvote}"></div>`;


    // Insert the elements to the queried tags
    for( var i=0; i<tags.length; i+=1 ) {
        tags[i].insertAdjacentHTML('beforeend' , elleft);
        tags[i].insertAdjacentHTML('beforeend' , elright);
    }

    dlog('insertElements() executed.');
}

function insertStylesheet() {
    var stylesheetEl = document.createElement('style');
    stylesheetEl.innerHTML = stylesheet;
    document.body.appendChild(stylesheetEl);
}

function hookEvents() {
    var voteups   = document.querySelectorAll('.qtvote.up');
    var votedowns = document.querySelectorAll('.qtvote.down');

    for(var i=0; i<voteups.length; i+=1) {
        voteups[i].addEventListener("click", quickVote);
    }

    for(var i=0; i<votedowns.length; i+=1) {
        votedowns[i].addEventListener("click", quickVote);
    }

    dlog('hookEvents() executed.');
}

function quickVote(e) {
    // Extract tagname and vote value
    var tag  = e.target.parentElement.id.substr(3);
    var vote = ( e.target.classList.toString().match('up') ? 1 : -1 );

    // Replace "_" with " " in   tag
    tag = tag.replace(/_/g, ' ');

    // Send the vote!
    unsafeWindow.send_vote(tag, vote);
    dlog("quickVote() executed");
    dlog(`tag = ${tag}`);
    dlog(`vote = ${vote}`);
}

function main() {
    insertStylesheet();
    insertElements();
    hookEvents();
    dlog("main() executed");
}

function init() {
    // Call main
    main();

    // Create a Mutation Observer, since the taglists are reloaded once the votes are sent
    var observer    = new MutationObserver(main);
    var target      = document.getElementById('taglist');
    var config      = { childList: true };
    observer.observe(target, config);
    dlog("MutationObserver is now observing #taglist");
}


// Init
// ----------
init();