您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Youtube Full Screen like Zooming for HackAPrompt Challenges
// ==UserScript== // @name HackAPrompt - Focus Mode 🎯 // @namespace KarthiDreamr.AI.RedTeam.Tools // @version 2.4 // @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; // default false; we'll explicitly apply Focus View on init let targetElement = null; let intervalId = null; // --- CSS Injection --- GM_addStyle(` /* --- FIX: Ensure the TabList remains visible --- */ body.${ISOLATED_BODY_CLASS} [data-hap-target="true"] [role="tablist"] { flex-shrink: 0 !important; } /* --- FIX: Ensure the bottom 'Points/Button' div remains visible --- */ 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 --- */ #${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; } /************************************************************** * 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; } `); // --- UI helpers --- const ICON_EXPAND = `<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"/>`; const ICON_CONTRACT = `<path d="M15 3h6v6m-11 5L21 3m-3 18h-6v-6m-1-5L3 21"/>`; function getButtonParts() { const button = document.getElementById(TOGGLE_BUTTON_ID); if (!button) return {}; return { button, textEl: button.querySelector('.toggle-text'), iconEl: button.querySelector('.toggle-icon') }; } function setButtonState({ label, iconPath }) { const { textEl, iconEl } = getButtonParts(); if (textEl) textEl.textContent = label; if (iconEl) iconEl.innerHTML = iconPath; } // --- Core Logic: explicit apply/revert to avoid accidental untoggles --- function applyFocus() { if (!targetElement) return; targetElement.setAttribute('data-hap-target', 'true'); document.body.classList.add(ISOLATED_BODY_CLASS); isIsolated = true; setButtonState({ label: 'Restore View', iconPath: ICON_CONTRACT }); console.log('HackAPrompt Script: View Focused.'); } function applyNormal() { if (!targetElement) return; targetElement.removeAttribute('data-hap-target'); document.body.classList.remove(ISOLATED_BODY_CLASS); isIsolated = false; setButtonState({ label: 'Focus View', iconPath: ICON_EXPAND }); console.log('HackAPrompt Script: View Restored.'); } function toggleView() { if (!targetElement) { console.warn('HackAPrompt Script: Cannot toggle, target element not found.'); return; } if (isIsolated) applyNormal(); else applyFocus(); } function createToggleButton() { if (document.getElementById(TOGGLE_BUTTON_ID)) return; 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"> ${ICON_EXPAND} </svg> <span class="toggle-text">Focus View</span>`; document.body.appendChild(button); button.addEventListener('click', toggleView); } function initialize() { if (document.getElementById(TOGGLE_BUTTON_ID) && targetElement) { if (intervalId) clearInterval(intervalId); return; } // Find the main two-column container 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(); // Apply Focus View by default on first init (without toggling away) if (!isIsolated) applyFocus(); if (intervalId) clearInterval(intervalId); } } // Polling mechanism 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); })();