☰

Highlight Text Search Buttons

Show search buttons when text is highlighted on specific websites

Du musst eine Erweiterung wie Tampermonkey, Greasemonkey oder Violentmonkey installieren, um dieses Skript zu installieren.

Um dieses Skript zu installieren, müssen Sie eine Erweiterung wie Tampermonkey oder Violentmonkey installieren.

Um dieses Skript zu installieren, müssen Sie eine Erweiterung wie Tampermonkey oder Violentmonkey installieren.

Um dieses Skript zu installieren, müssen Sie eine Erweiterung wie Tampermonkey oder Userscripts installieren.

Um dieses Skript zu installieren, müssen Sie eine Erweiterung wie Tampermonkey installieren.

Sie müssten eine Skript Manager Erweiterung installieren damit sie dieses Skript installieren können

(Ich habe schon ein Skript Manager, Lass mich es installieren!)

Um dieses Design zu installieren, müssen Sie eine Erweiterung wie Stylus installieren.

Um dieses Design zu installieren, müssen Sie eine Erweiterung wie Stylus installieren.

Um dieses Design zu installieren, müssen Sie eine Erweiterung wie Stylus installieren.

Um diesen Stil zu installieren, müssen Sie eine Erweiterung für den Benutzerstil Verwaltung installieren.

Um diesen Stil zu installieren, müssen Sie eine Erweiterung für den Benutzerstil Verwaltung installieren.

Um diesen Stil zu installieren, müssen Sie eine Erweiterung für den Benutzerstil Verwaltung installieren.

(Ich habe bereits einen Benutzerstil Verwaltung, ich möchte ihn installieren!)

// ==UserScript==
// @name         Highlight Text Search Buttons
// @namespace    http://tampermonkey.net/
// @version      2.1
// @description  Show search buttons when text is highlighted on specific websites
// @match        *://onlyfans.com/*
// @match        *://camwhores.tv/*
// @match        https://www.camwhores.tv/*
// @match         https://www.showcamrips.com/*
// @match        *://livecamrips.to/*
// @match        *://simpcity.cr/*
// @match        *://forums.socialmediagirls.com/*
// @match        *://camgirlfinder.net/*
// @match        *://nrtool.st/*
// @match         *://archivebate.com/*
// @match         *://nobodyhome.ws/*
// @match         *://camsmut.com/*
// @match         *://stripchat.com/*
// @match         *://*.bongocams.com/*
// @match         *://www.sexycamx.com/*
// @match         *://chaturbate.com/*
// @match         *://striptube.cc/*
// @match         *://forums.socialmediagirls.com/*
// @match         *://recu.me/*
// @match         *://camripvault.site/*
// @grant        GM_openInTab
// @grant        unsafeWindow
// @license MIT
// ==/UserScript==
(function() {
    'use strict';

    // ============ CONFIGURATION ============

    // Default search sites configuration
    const defaultSites = [
        { name: 'camripvault', url: 'https://camripvault.site/browse?query={username}' },
        { name: 'showcamrips', url: 'https://showcamrips.com/model/en/{username}/' },
        { name: 'livecamrips', url: 'https://www.livecamrips.to/search/{username}/1' },
        { name: 'archivebate', url: 'https://archivebate.com/profile/{username}' },
        { name: 'camsmut', url: 'https://camsmut.com/search?q={username}//' },
        { name: 'camwhores', url: 'https://camwhores.tv/search/{username}/' },
        { name: 'nobodyhome', url: 'https://nobodyhome.ws/search.php?action=do_search&postthread=1&keywords={username}' },
        { name: 'camgirlfinder', url: 'https://camgirlfinder.net/models?model={username}&platform=&gender=' },
        { name: 'nrtool', url: 'https://nrtool.st/nrtool/search?s={username}' },
        { name: 'simpcity', url: 'https://simpcity.cr/search/1/?q={username}' },
        { name: 'socialmediagirls', url: 'https://forums.socialmediagirls.com/search/579063442/?q={username}&o=relevance' },
        { name: 'bongocams', url: 'https://ru3.bongocams.com/{username}' },
        { name: 'stripchat', url: 'https://stripchat.com/{username}' },
        { name: 'onlyfans', url: 'https://onlyfans.com/{username}' },
        { name: 'sexycamx', url: 'https://www.sexycamx.com/{username}' },
        { name: 'recume', url: 'https://recu.me/performer/{username}' },
        { name: 'striphub', url: 'https://striptube.cc/performer/{username}' }
    ];


    // ============ SCRIPT LOGIC ============

    let buttonContainer = null;
    let selectedText = '';
    let useLowercase = false;

    // Enhanced function to open URL in new tab (bypasses site restrictions)
    function openUrlInNewTab(url) {
        // Method 1: Try GM_openInTab if available (most reliable)
        if (typeof GM_openInTab !== 'undefined') {
            try {
                GM_openInTab(url, { active: false, insert: true });
                return;
            } catch (e) {
                console.log('GM_openInTab failed, trying alternatives');
            }
        }

        // Method 2: Create a temporary anchor element with download attribute trick
        try {
            const a = document.createElement('a');
            a.href = url;
            a.target = '_blank';
            a.rel = 'noopener noreferrer';

            // This helps bypass some restrictions
            a.style.display = 'none';
            document.body.appendChild(a);

            // Dispatch a real click event
            const evt = new MouseEvent('click', {
                bubbles: true,
                cancelable: true,
                view: window
            });
            a.dispatchEvent(evt);

            // Clean up
            setTimeout(() => document.body.removeChild(a), 100);
            return;
        } catch (e) {
            console.log('Anchor method failed, trying window.open');
        }

        // Method 3: Standard window.open with enhanced parameters
        try {
            const newWindow = window.open(url, '_blank', 'noopener,noreferrer');
            if (newWindow) {
                newWindow.opener = null;
            }
        } catch (e) {
            // Method 4: Last resort - use location.href in a timeout
            console.log('All methods failed, using location fallback');
            setTimeout(() => {
                window.location.href = url;
            }, 100);
        }
    }

    // Create button container
    function createButtonContainer() {
        const container = document.createElement('div');
        container.id = 'highlight-search-container';
        container.style.cssText = `
            position: fixed;
            bottom: 20px;
            right: 20px;
            display: none;
            flex-direction: column;
            gap: 6px;
            z-index: 999999;
            padding: 10px;
            background: rgba(255, 255, 255, 0.98);
            border-radius: 10px;
            box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
            backdrop-filter: blur(10px);
            border: 1px solid rgba(0, 0, 0, 0.1);
            max-width: 180px;
            max-height: 80vh;
            overflow-y: auto;
        `;

        // Add title
        const title = document.createElement('div');
        title.textContent = 'Search with:';
        title.style.cssText = `
            font-size: 11px;
            font-weight: 600;
            color: #666;
            margin-bottom: 2px;
            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
        `;
        container.appendChild(title);

        // Add lowercase checkbox
        const checkboxContainer = document.createElement('label');
        checkboxContainer.style.cssText = `
            display: flex;
            align-items: center;
            gap: 6px;
            font-size: 11px;
            color: #666;
            margin-bottom: 4px;
            cursor: pointer;
            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
        `;

        const checkbox = document.createElement('input');
        checkbox.type = 'checkbox';
        checkbox.checked = useLowercase;
        checkbox.style.cssText = `
            cursor: pointer;
            width: 14px;
            height: 14px;
        `;

        checkbox.addEventListener('change', (e) => {
            useLowercase = e.target.checked;
        });

        const checkboxLabel = document.createElement('span');
        checkboxLabel.textContent = 'Lowercase';

        checkboxContainer.appendChild(checkbox);
        checkboxContainer.appendChild(checkboxLabel);
        container.appendChild(checkboxContainer);

        // Create buttons
        defaultSites.forEach(site => {
            const button = document.createElement('button');
            button.textContent = site.name;
            button.style.cssText = `
                padding: 6px 10px;
                background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
                color: white;
                border: none;
                border-radius: 6px;
                cursor: pointer;
                font-size: 12px;
                font-weight: 500;
                font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
                transition: all 0.2s ease;
                white-space: nowrap;
                text-align: center;
            `;

            button.addEventListener('mouseenter', () => {
                button.style.transform = 'translateY(-1px)';
                button.style.boxShadow = '0 2px 8px rgba(0, 0, 0, 0.2)';
            });

            button.addEventListener('mouseleave', () => {
                button.style.transform = 'translateY(0)';
                button.style.boxShadow = 'none';
            });

            button.addEventListener('click', (e) => {
                e.preventDefault();
                e.stopPropagation();

                const username = useLowercase ? selectedText.toLowerCase() : selectedText;
                const finalUrl = site.url.replace('{username}', encodeURIComponent(username));

                openUrlInNewTab(finalUrl);
            });

            container.appendChild(button);
        });

        // Add close button
        const closeBtn = document.createElement('button');
        closeBtn.textContent = '✕';
        closeBtn.style.cssText = `
            position: absolute;
            top: 6px;
            right: 6px;
            width: 20px;
            height: 20px;
            border: none;
            background: rgba(0, 0, 0, 0.1);
            border-radius: 50%;
            cursor: pointer;
            font-size: 12px;
            color: #666;
            display: flex;
            align-items: center;
            justify-content: center;
            transition: all 0.2s ease;
        `;

        closeBtn.addEventListener('mouseenter', () => {
            closeBtn.style.background = 'rgba(0, 0, 0, 0.2)';
        });

        closeBtn.addEventListener('mouseleave', () => {
            closeBtn.style.background = 'rgba(0, 0, 0, 0.1)';
        });

        closeBtn.addEventListener('click', () => {
            container.style.display = 'none';
        });

        container.appendChild(closeBtn);
        document.body.appendChild(container);
        return container;
    }

    // Handle text selection
    function handleTextSelection() {
        const selection = window.getSelection();
        const text = selection.toString().trim();

        if (text.length > 0) {
            selectedText = text;
            if (!buttonContainer) {
                buttonContainer = createButtonContainer();
            }
            buttonContainer.style.display = 'flex';
        } else {
            if (buttonContainer) {
                buttonContainer.style.display = 'none';
            }
        }
    }

    // Event listeners
    document.addEventListener('mouseup', handleTextSelection);
    document.addEventListener('keyup', handleTextSelection);
    document.addEventListener('selectionchange', handleTextSelection);

    // Hide buttons when clicking outside
    document.addEventListener('click', (e) => {
        if (buttonContainer && !buttonContainer.contains(e.target)) {
            const selection = window.getSelection();
            if (selection.toString().trim().length === 0) {
                buttonContainer.style.display = 'none';
            }
        }
    });

})();