KCE - Search Model on Web

Floating search panel restricted only to model profiles

이 스크립트를 설치하려면 Tampermonkey, Greasemonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

이 스크립트를 설치하려면 Tampermonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Userscripts와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 유저 스크립트 관리자 확장 프로그램이 필요합니다.

(이미 유저 스크립트 관리자가 설치되어 있습니다. 설치를 진행합니다!)

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

(이미 유저 스타일 관리자가 설치되어 있습니다. 설치를 진행합니다!)

// ==UserScript==
// @name         KCE - Search Model on Web
// @namespace    kce_search_model_on_web_userscript
// @version      15.5
// @description  Floating search panel restricted only to model profiles
// @author       KCE
// @icon         data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><text y=".9em" font-size="85">👤</text></svg>
// @match        *://*.xhamster.com/pornstars/*
// @match        *://*.xhamster.com/creators/*
// @match        *://*.xhamster.com/channels/*
// @match        *://*.xhamster.com/users/*
// @match        *://*.pornhub.com/model/*
// @match        *://*.pornhub.com/pornstar/*
// @match        *://*.pornhub.com/channels/*
// @match        *://*.xvideos.com/models/*
// @match        *://*.xvideos.com/profiles/*
// @match        *://*.xvideos.com/channels/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    const siteSelectors = {
        'pornhub.com': [
            '.name h1[itemprop="name"]',
            '.floatLeft.titleWrapper > div.title.floatLeft > h1'
        ],
        'xvideos.com': [
            '.text-danger',
            '#profile-title > div.profile-infos:last-child > div:first-child > h2.with-aka:last-child > strong.text-danger:nth-child(2)'
        ],
        'xhamster.com': [
            'div.main-wrap:nth-child(4) > div.layoutPage:nth-child(4) > div.user-header.user-header--small:first-child > div.width-wrap > div.user-info-section:nth-child(2) > div.user-top-infoblock:first-child > div.user-name:first-child > a.value:first-child',
            'div.user-profile-header__name-row > h1',
            '.h3-bold-8643e.primary-8643e.landing-info__user-title',
            '.item-50dd2',
            'div.wrapper.settingsPage:nth-child(12) > div.container.amateur-view-page:last-child > div.amateurModel.noBio:nth-child(8) > div.withCover > section.topProfileHeader > div.coverImage:nth-child(2) > div.bottomGradient:nth-child(2) > div.nameSubscribe > div.name:first-child',
            'div.main-wrap:nth-child(4) > div.layoutPage:nth-child(4) > main:first-child > div.width-wrap > article.pornstar-container > div.category-info.pornstar.with-tabs:first-child > div.pornstar-info:first-child > div.landing-info > div.landing-info__wrapper > div.landing-info__user.landing-info__user--space-between:last-child > div:first-child > div.landing-info__user-name > h2.h3-bold-8643e.primary-8643e.landing-info__user-title:first-child'
        ]
    };

    const hostname = window.location.hostname;
    let selectors = null;

    for (const site in siteSelectors) {
        if (hostname.includes(site)) {
            selectors = siteSelectors[site];
            break;
        }
    }

    if (!selectors) return;

    let panelInstance = null;
    let lastUsername = null;

    function getUsername() {
        for (const selector of selectors) {
            const el = document.querySelector(selector);
            if (el) {
                const text = el.textContent.trim();
                if (text) return text;
            }
        }
        return null;
    }

    function createOrUpdatePanel() {
        const username = getUsername();
        if (!username) {
            if (panelInstance) {
                panelInstance.remove();
                panelInstance = null;
                lastUsername = null;
            }
            return;
        }

        if (username === lastUsername && panelInstance && document.body.contains(panelInstance)) return;
        lastUsername = username;

        if (panelInstance && document.body.contains(panelInstance)) {
            updatePanelLinks(panelInstance, username);
            return;
        }

        panelInstance = document.createElement('div');
        panelInstance.id = 'kce-floating-panel';
        panelInstance.style.position = 'fixed';
        panelInstance.style.bottom = '20px';
        panelInstance.style.right = '20px';
        panelInstance.style.zIndex = '999999';
        panelInstance.style.background = 'rgba(20, 20, 20, 0.9)';
        panelInstance.style.backdropFilter = 'blur(10px)';
        panelInstance.style.border = '1px solid rgba(255, 255, 255, 0.15)';
        panelInstance.style.borderRadius = '12px';
        panelInstance.style.padding = '10px 14px';
        panelInstance.style.boxShadow = '0 8px 32px rgba(0, 0, 0, 0.4)';
        panelInstance.style.display = 'flex';
        panelInstance.style.flexDirection = 'column';
        panelInstance.style.gap = '8px';
        panelInstance.style.fontFamily = '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
        panelInstance.style.color = '#fff';
        panelInstance.style.transition = 'opacity 0.3s ease';

        const header = document.createElement('div');
        header.style.display = 'flex';
        header.style.justifyContent = 'space-between';
        header.style.alignItems = 'center';
        header.style.fontSize = '11px';
        header.style.color = '#aaa';
        header.style.borderBottom = '1px solid rgba(255, 255, 255, 0.1)';
        header.style.paddingBottom = '4px';

        const title = document.createElement('span');
        title.textContent = 'Search model on web 🤔';
        header.appendChild(title);

        const closeBtn = document.createElement('span');
        closeBtn.textContent = '×';
        closeBtn.style.cursor = 'pointer';
        closeBtn.style.fontSize = '14px';
        closeBtn.style.fontWeight = 'bold';
        closeBtn.onclick = () => {
            if (panelInstance) panelInstance.remove();
            panelInstance = null;
        };
        header.appendChild(closeBtn);

        panelInstance.appendChild(header);

        const linksContainer = document.createElement('div');
        linksContainer.id = 'kce-links-container';
        linksContainer.style.display = 'flex';
        linksContainer.style.gap = '6px';
        panelInstance.appendChild(linksContainer);

        updatePanelLinks(panelInstance, username);
        document.body.appendChild(panelInstance);
    }

    function updatePanelLinks(panel, username) {
        const container = panel.querySelector('#kce-links-container');
        if (!container) return;
        container.innerHTML = '';

        const engines = [
            { name: 'Y', fullName: 'Yandex', url: `https://yandex.com/search/?text=${encodeURIComponent(username)}`, color: '#fc3f1d' },
            { name: 'G', fullName: 'Google', url: `https://www.google.com/search?q=${encodeURIComponent(username)}`, color: '#4285F4' },
            { name: 'B', fullName: 'Bing', url: `https://www.bing.com/search?q=${encodeURIComponent(username)}`, color: '#00b294' },
            { name: 'V', fullName: 'Brave', url: `https://search.brave.com/search?q=${encodeURIComponent(username)}`, color: '#FB542B' },
            { name: 'D', fullName: 'DuckDuckGo', url: `https://duckduckgo.com/?q=${encodeURIComponent(username)}`, color: '#DE5833' }
        ];

        engines.forEach(engine => {
            const anchor = document.createElement('a');
            anchor.href = engine.url;
            anchor.target = '_blank';
            anchor.title = engine.fullName;
            anchor.textContent = engine.name;
            anchor.style.display = 'flex';
            anchor.style.alignItems = 'center';
            anchor.style.justifyContent = 'center';
            anchor.style.width = '32px';
            anchor.style.height = '32px';
            anchor.style.borderRadius = '8px';
            anchor.style.background = 'rgba(255, 255, 255, 0.08)';
            anchor.style.color = engine.color;
            anchor.style.fontSize = '14px';
            anchor.style.fontWeight = '900';
            anchor.style.textDecoration = 'none';
            anchor.style.transition = 'all 0.2s ease';

            anchor.onmouseover = () => {
                anchor.style.background = 'rgba(255, 255, 255, 0.15)';
                anchor.style.transform = 'translateY(-2px)';
                anchor.style.boxShadow = `0 4px 12px ${engine.color}44`;
            };
            anchor.onmouseout = () => {
                anchor.style.background = 'rgba(255, 255, 255, 0.08)';
                anchor.style.transform = 'translateY(0)';
                anchor.style.boxShadow = 'none';
            };

            container.appendChild(anchor);
        });
    }

    createOrUpdatePanel();
    setInterval(createOrUpdatePanel, 1500);

})();