NH ↔ EH Crosslinker

Adds cross-links between nhentai and e-hentai/exhentai galleries

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey, Greasemonkey of Violentmonkey.

Voor het installeren van scripts heb je een extensie nodig, zoals {tampermonkey_link:Tampermonkey}.

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey of Violentmonkey.

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey of Userscripts.

Voor het installeren van scripts heb je een extensie nodig, zoals {tampermonkey_link:Tampermonkey}.

Voor het installeren van scripts heb je een gebruikersscriptbeheerder nodig.

(Ik heb al een user script manager, laat me het downloaden!)

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

(Ik heb al een beheerder - laat me doorgaan met de installatie!)

// ==UserScript==
// @name         NH ↔ EH Crosslinker
// @namespace    github.com/longkidkoolstar
// @version      0.3.0
// @description  Adds cross-links between nhentai and e-hentai/exhentai galleries
// @author       longkidkoolstar
// @match        https://nhentai.net/g/*
// @match        https://e-hentai.org/g/*
// @match        https://exhentai.org/g/*
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_registerMenuCommand
// @license      MIT
// @icon         https://i.postimg.cc/fb6L0sx9/e-h.png
// ==/UserScript==
(function () {
    'use strict';
    const url = location.href;

    // --- Settings & Menu ---
    const PREF_KEY = 'search_title_type';
    const PREF_DISPLAY = {
        'english': 'English',
        'romanized': 'Romanized',
        'japanese': 'Japanese'
    };

    function getPreferredTitleType() {
        return GM_getValue(PREF_KEY, 'english');
    }

    function setPreferredTitleType(type) {
        GM_setValue(PREF_KEY, type);
        location.reload();
    }

    // Register Menu Commands
    const currentType = getPreferredTitleType();
    GM_registerMenuCommand(`Search with English Title ${currentType === 'english' ? '✅' : ''}`, () => setPreferredTitleType('english'));
    GM_registerMenuCommand(`Search with Romanized Title ${currentType === 'romanized' ? '✅' : ''}`, () => setPreferredTitleType('romanized'));
    GM_registerMenuCommand(`Search with Japanese Title ${currentType === 'japanese' ? '✅' : ''}`, () => setPreferredTitleType('japanese'));

    // --- Title Logic ---
    function getTitle(site) {
        const type = getPreferredTitleType();
        let title = '';

        if (site === 'nhentai') {
            const h1 = document.querySelector('#info h1'); // Pretty/English/Romanized
            const h2 = document.querySelector('#info h2'); // Original/Japanese

            if (type === 'japanese' && h2 && h2.innerText.trim()) {
                title = h2.innerText;
            } else if (h1) {
                title = h1.innerText;
            }
        } else if (site === 'ehentai') {
            const gn = document.querySelector('#gn'); // English/Romanized
            const gj = document.querySelector('#gj'); // Japanese

            if (type === 'japanese' && gj && gj.innerText.trim()) {
                title = gj.innerText;
            } else if (gn) {
                title = gn.innerText;
            } else if (gj) {
                title = gj.innerText;
            }
        }
        
        return cleanTitle(title, type);
    }

    /* ---------------- NHENTAI → E-HENTAI ---------------- */
    if (url.includes('nhentai.net/g/')) {
        const title = getTitle('nhentai');
        if (!title) return;

        const artistEl = document.querySelector(
            '.tag-container.field-name a[href^="/artist/"] .name'
        );
        const artist = artistEl ? artistEl.textContent.trim() : '';
        let query = title;
        if (artist) query += ` artist:${artist}`;
        const ehUrl = 'https://e-hentai.org/?f_search=' + encodeURIComponent(query);
        addButton('#info', `🔗 Search on e-hentai (${PREF_DISPLAY[currentType]})`, ehUrl);
        return;
    }

    /* ---------------- E / EXHENTAI → NHENTAI ---------------- */
    if (url.includes('e-hentai.org/g/') || url.includes('exhentai.org/g/')) {
        const title = getTitle('ehentai');
        if (!title) return;

        const artistEl = document.querySelector(
            '#taglist a[href^="https://e-hentai.org/tag/artist:"]'
        );
        const artist = artistEl ? artistEl.textContent.trim() : '';
        let query = title;
        if (artist) query += ` ${artist}`;
        const nhUrl =
            'https://nhentai.net/search/?q=' + encodeURIComponent(query);
        addButton('#gd2', `🔗 Search on nhentai (${PREF_DISPLAY[currentType]})`, nhUrl);
    }

    /* ---------------- SWITCH e-hentai → exhentai ---------------- */
    if (
        url.startsWith('https://e-hentai.org/?') ||
        url.startsWith('https://e-hentai.org/?f_search=')
    ) {
        const exhUrl = url.replace('https://e-hentai.org/', 'https://exhentai.org/');
        addFloatingButton('🔄 Switch to exhentai', exhUrl);
    }

    /* ---------------- Helpers ---------------- */
    function cleanTitle(title, type) {
        if (!title) return '';
        // If title contains |, take only the left part
        if (title.includes('|')) {
            if (type === 'english') {
                // For English, take the right part
                title = title.split('|')[1];
            } else {
                // For others (e.g. Romanized), take the left part
                title = title.split('|')[0];
            }
        }

        // Remove bracketed content
        title = title.replace(/\[[^\]]*\]/g, '');

        // Remove numbers (standalone digits and sequences)
        title = title.replace(/\b\d+\b/g, '');

        // Clean up extra whitespace
        title = title.replace(/\s+/g, ' ').trim();

        return title;
    }

    function addButton(parentSelector, text, link) {
        const parent = document.querySelector(parentSelector);
        if (!parent) return;
        const a = document.createElement('a');
        a.href = link;
        a.target = '_blank';
        a.textContent = text;
        a.style.display = 'block';
        a.style.marginTop = '10px';
        a.style.fontSize = '16px';
        parent.appendChild(a);
    }

    function addFloatingButton(text, link) {
        const a = document.createElement('a');
        a.href = link;
        a.textContent = text;
        a.style.position = 'fixed';
        a.style.bottom = '20px';
        a.style.right = '20px';
        a.style.padding = '10px 14px';
        a.style.background = '#34353b';
        a.style.color = '#fff';
        a.style.borderRadius = '6px';
        a.style.fontSize = '14px';
        a.style.zIndex = '9999';
        a.style.textDecoration = 'none';
        document.body.appendChild(a);
    }
})();