您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Youtube Full Screen like Zooming for HackAPrompt Challenges
// ==UserScript== // @name HackAPrompt - Focus Mode 🎯 // @namespace KarthiDreamr.AI.RedTeam.Tools // @version 2.2 // @description Youtube Full Screen like Zooming for HackAPrompt Challenges // @author KarthiDreamr & Perplexity (Logic updated by Gemini) // @match https://www.hackaprompt.com/* // @grant GM_addStyle // @run-at document-idle // @license MIT // ==/UserScript== (function() { 'use strict'; // --- URL Validation: Only run on URLs with exactly 2 segments after /track/ --- function isValidURL() { const pathname = window.location.pathname; // Regex pattern: /track/[segment1]/[segment2] (with optional trailing slash) const pattern = /^\/track\/[^\/]+\/[^\/]+\/?$/; return pattern.test(pathname); } // Early exit if URL doesn't match the required pattern if (!isValidURL()) { console.log('HackAPrompt Script: URL does not match required pattern. Script will not run.'); return; } console.log('HackAPrompt Script: Valid URL detected. Initializing...'); // --- Configuration --- const TOGGLE_BUTTON_ID = "hap-isolate-toggle-button"; const ISOLATED_BODY_CLASS = "hap-isolated-view-active"; // --- State Variables --- let isIsolated = false; let targetElement = null; let intervalId = null; // --- CSS Injection --- GM_addStyle(` /* --- FIX: Ensure the TabList remains visible --- */ /* This tells the row of tab buttons not to shrink, even when its container is in flex mode. */ body.${ISOLATED_BODY_CLASS} [data-hap-target="true"] [role="tablist"] { flex-shrink: 0 !important; } /* --- FIX: Ensure the bottom 'Points/Button' div remains visible --- */ /* This targets the div with the 'sm:mt-auto' class and tells it not to shrink. */ body.${ISOLATED_BODY_CLASS} [data-hap-target="true"] .sm\\:mt-auto { flex-shrink: 0 !important; padding-bottom: 2.3rem !important; /* Adds a little space at the bottom */ } /* --- Toggle Button Styles (unchanged) --- */ #${TOGGLE_BUTTON_ID} { position: fixed; bottom: 20px; left: 20px; z-index: 999999; /* Must be higher than the focused element */ background-color: #1a202c; color: #e2e8f0; border: 1px solid #4a5568; border-radius: 25px; padding: 8px; cursor: pointer; display: flex; align-items: center; box-shadow: 0 4px 12px rgba(0,0,0,0.4); transition: all 0.3s ease; overflow: hidden; width: 40px; height: 40px; } #${TOGGLE_BUTTON_ID}:hover { width: 170px; } #${TOGGLE_BUTTON_ID} .toggle-icon { flex-shrink: 0; width: 24px; height: 24px; margin: 0; transition: transform 0.3s ease; } #${TOGGLE_BUTTON_ID} .toggle-text { white-space: nowrap; opacity: 0; transition: opacity 0.2s ease 0.1s; font-family: sans-serif; font-size: 14px; margin-left: 8px; } #${TOGGLE_BUTTON_ID}:hover .toggle-text { opacity: 1; } /************************************************************** * NEW LOGIC: Promote the target element instead of hiding others **************************************************************/ /* 1. When active, lift the target element and make it a full-screen overlay */ body.${ISOLATED_BODY_CLASS} [data-hap-target="true"] { position: fixed !important; top: 0 !important; left: 0 !important; width: 100vw !important; height: 100vh !important; z-index: 999990 !important; /* High z-index to cover page content */ background: #0F172A !important; /* Add a background color to hide content underneath */ padding: 0 !important; margin-top: 0 !important; display: flex !important; flex-direction: row !important; } /* 2. Prevent the body from scrolling while in focus mode */ body.${ISOLATED_BODY_CLASS} { overflow: hidden !important; } /************************************************************** * FULL HEIGHT STYLES (These are still needed for the internals) **************************************************************/ body.${ISOLATED_BODY_CLASS} [data-hap-target="true"] .flex-1 { flex-grow: 1 !important; min-height: 0 !important; display: flex !important; flex-direction: column !important; } body.${ISOLATED_BODY_CLASS} [data-hap-target="true"] [role="tabpanel"], body.${ISOLATED_BODY_CLASS} [data-hap-target="true"] .overflow-y-auto { height: 100% !important; max-height: none !important; flex: 1 !important; } body.${ISOLATED_BODY_CLASS} [data-hap-target="true"] textarea { min-height: 200px !important; flex-grow: 1 !important; } body.${ISOLATED_BODY_CLASS} .h-\\[calc\\(100dvh-8rem\\)\\] { height: 100% !important; } body.${ISOLATED_BODY_CLASS} .h-\\[calc\\(100dvh-13rem\\)\\] { height: 100% !important; flex: 1 !important; } body.${ISOLATED_BODY_CLASS} .lg\\:h-\\[calc\\(100dvh-8rem\\)\\] { height: 100% !important; } `); // --- Core Logic --- function createToggleButton() { const button = document.createElement('div'); button.id = TOGGLE_BUTTON_ID; button.title = "Toggle Focus View"; button.innerHTML = ` <svg class="toggle-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3"/> </svg> <span class="toggle-text">Focus View</span>`; document.body.appendChild(button); button.addEventListener('click', toggleView); } // --- UPDATED toggleView Function (Much Simpler) --- function toggleView() { if (!targetElement) { console.warn('HackAPrompt Script: Cannot toggle, target element not found.'); return; } isIsolated = !isIsolated; const button = document.getElementById(TOGGLE_BUTTON_ID); const buttonText = button.querySelector('.toggle-text'); const buttonIcon = button.querySelector('.toggle-icon'); if (isIsolated) { // --- ISOLATE --- // No more moving elements! Just add classes and attributes. targetElement.setAttribute('data-hap-target', 'true'); document.body.classList.add(ISOLATED_BODY_CLASS); buttonText.textContent = "Restore View"; buttonIcon.innerHTML = `<path d="M15 3h6v6m-11 5L21 3m-3 18h-6v-6m-1-5L3 21"/>`; // Contract icon console.log('HackAPrompt Script: View Focused.'); } else { // --- RESTORE --- // Just remove the classes and attributes. targetElement.removeAttribute('data-hap-target'); document.body.classList.remove(ISOLATED_BODY_CLASS); buttonText.textContent = "Focus View"; buttonIcon.innerHTML = `<path d="M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3"/>`; // Expand icon console.log('HackAPrompt Script: View Restored.'); } } function initialize() { if (document.getElementById(TOGGLE_BUTTON_ID)) { if (intervalId) clearInterval(intervalId); return; } // Finding logic is unchanged const allFlexRows = document.querySelectorAll('div.lg\\:flex-row'); let foundElement = null; for (const container of allFlexRows) { const leftPanel = container.querySelector(':scope > div[class*="lg:w-[40%]"]'); const rightPanel = container.querySelector(':scope > div[class*="lg:w-[58%]"]'); if (leftPanel && rightPanel) { foundElement = container; break; } } targetElement = foundElement; if (targetElement) { console.log('HackAPrompt Isolate Script: Target element located. Initializing controls.'); createToggleButton(); if (intervalId) clearInterval(intervalId); } } // Polling mechanism (unchanged) intervalId = setInterval(initialize, 500); setTimeout(() => { if (intervalId) { clearInterval(intervalId); if (!targetElement) { console.warn('HackAPrompt Script: Target element could not be found after 20 seconds.'); } } }, 20000); })();