YouTube New Window Player

点击YouTube视频时自动在新窗口播放,并提供开关控制,支持中键显示/隐藏UI。

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

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

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

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

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

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

ستحتاج إلى تثبيت إضافة مثل Stylus لتثبيت هذا النمط.

ستحتاج إلى تثبيت إضافة لإدارة أنماط المستخدم لتتمكن من تثبيت هذا النمط.

ستحتاج إلى تثبيت إضافة لإدارة أنماط المستخدم لتثبيت هذا النمط.

ستحتاج إلى تثبيت إضافة لإدارة أنماط المستخدم لتثبيت هذا النمط.

(لدي بالفعل مثبت أنماط للمستخدم، دعني أقم بتثبيته!)

// ==UserScript==
// @name         YouTube New Window Player
// @namespace    http://tampermonkey.net/
// @version      0.3
// @description  点击YouTube视频时自动在新窗口播放,并提供开关控制,支持中键显示/隐藏UI。
// @author       醉春风
// @match        https://www.youtube.com/*
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_addStyle
// @run-at       document-start
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    const SCRIPT_TOGGLE_KEY = 'youtubeNewWindowPlayerEnabled';
    const UI_VISIBLE_KEY = 'youtubeNewWindowPlayerUIVisible';
    let isEnabled = GM_getValue(SCRIPT_TOGGLE_KEY, true); // Default to enabled
    let isUIVisible = GM_getValue(UI_VISIBLE_KEY, true); // Default to UI visible

    // Add CSS for the button and its hidden state
    GM_addStyle(`
        #youtube-new-window-toggle {
            position: fixed;
            bottom: 20px;
            right: 20px;
            z-index: 9999;
            padding: 10px 15px;
            background-color: ${isEnabled ? '#28a745' : '#dc3545'};
            color: white;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            font-size: 14px;
            box-shadow: 0 2px 5px rgba(0,0,0,0.2);
            transition: background-color 0.3s ease, opacity 0.3s ease;
        }
        #youtube-new-window-toggle.hidden {
            opacity: 0;
            pointer-events: none; /* Make it unclickable when hidden */
        }
    `);

    function createToggleButton() {
        const button = document.createElement('button');
        button.id = 'youtube-new-window-toggle';
        button.textContent = isEnabled ? '新窗口播放: 开' : '新窗口播放: 关';
        button.style.backgroundColor = isEnabled ? '#28a745' : '#dc3545';
        if (!isUIVisible) {
            button.classList.add('hidden');
        }

        button.addEventListener('click', () => {
            isEnabled = !isEnabled;
            GM_setValue(SCRIPT_TOGGLE_KEY, isEnabled);
            button.textContent = isEnabled ? '新窗口播放: 开' : '新窗口播放: 关';
            button.style.backgroundColor = isEnabled ? '#28a745' : '#dc3545';
            console.log('YouTube New Window Player is now ' + (isEnabled ? 'enabled' : 'disabled'));
        });

        document.body.appendChild(button);
    }

    function handleVideoClick(event) {
        // Allow middle-click to open in new tab by default browser behavior
        if (event.button === 1) { // Middle mouse button
            return;
        }

        if (!isEnabled) {
            return;
        }

        let target = event.target;
        let videoLink = null;

        // Traverse up the DOM to find the closest video link (a tag or element with href to /watch?v=)
        while (target && target !== document.body) {
            if (target.tagName === 'A' && target.href && target.href.includes('/watch?v=')) {
                videoLink = target;
                break;
            }
            // For elements that might not be <a> but contain a video link (e.g., div with data-yt-id)
            if (target.dataset && target.dataset.videoId) {
                videoLink = target;
                break;
            }
            target = target.parentElement;
        }

        if (videoLink) {
            let videoUrl = videoLink.href || `https://www.youtube.com/watch?v=${videoLink.dataset.videoId}`;

            if (videoUrl && videoUrl.includes('/watch?v=')) {
                event.preventDefault(); // Prevent default navigation
                event.stopPropagation(); // Stop event propagation to prevent other YouTube handlers
                window.open(videoUrl, '_blank', 'noopener,noreferrer'); // Add security features
            }
        }
    }

    function toggleUIButtonVisibility(event) {
        if (event.button === 1) { // Middle mouse button
            const button = document.getElementById('youtube-new-window-toggle');
            if (button) {
                isUIVisible = !isUIVisible;
                GM_setValue(UI_VISIBLE_KEY, isUIVisible);
                if (isUIVisible) {
                    button.classList.remove('hidden');
                } else {
                    button.classList.add('hidden');
                }
                console.log('YouTube New Window Player UI is now ' + (isUIVisible ? 'visible' : 'hidden'));
            }
        }
    }

    // Use document-start to attach event listener as early as possible
    document.addEventListener('click', handleVideoClick, true); // Use capture phase

    // Listen for middle mouse clicks on the document to toggle UI visibility
    document.addEventListener('mousedown', toggleUIButtonVisibility);

    // Ensure the button is created once the DOM is ready
    window.addEventListener('DOMContentLoaded', createToggleButton);

})();