buba_buba / Codeforces Toggle

// ==UserScript==
// @name         Codeforces Toggle
// @namespace    http://codeforces.com/
// @version      2.7
// @description  在 Codeforces 题目页隐藏侧边栏和顶部按钮(已转到https://openuserjs.org/scripts/buba_buba/Codeforces_Sidebar_Toggle)
// @match        https://codeforces.com/problemset/problem/*/*
// @match        https://codeforces.com/contest/*/problem/*
// @match        https://codeforces.com/gym/*/problem/*
// @match        https://codeforces.com/group/*/contest/*/problem/*
// @grant        none
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    const STORAGE_KEY = 'cf_auto_simple_mode';

    class SimpleModeManager {
        constructor() {
            this.isActive = false;
            this.hiddenElements = [];
            this.styleElement = null;
        }

        createStyle() {
            if (!this.styleElement) {
                this.styleElement = document.createElement('style');
                this.styleElement.textContent = `
                    body.cf-simple-mode {
                        overflow-x: hidden !important;
                    }
                    .content-without-sidebar #pageContent {
                        width: 100% !important;
                        margin-left: 0 !important;
                    }
                    body.zoomed {
                        transform-origin: top left;
                        transform: scale(1.15);
                        width: calc(100vw / 1.15);
                    }
                `;
                document.head.appendChild(this.styleElement);
            }
        }

        removeStyle() {
            if (this.styleElement) {
                this.styleElement.remove();
                this.styleElement = null;
            }
        }

        hideElement(selector, parent = document) {
            const elements = Array.from(parent.querySelectorAll(selector));
            elements.forEach(el => {
                this.hiddenElements.push({
                    element: el,
                    originalDisplay: el.style.display
                });
                el.style.display = 'none';
            });
        }

        restoreHiddenElements() {
            this.hiddenElements.forEach(item => {
                item.element.style.display = item.originalDisplay;
            });
            this.hiddenElements = [];
        }

        hideTopButtons() {
            const selectors = [
                '.topRightDiv > a:not(:first-child)',
                '.topRightDiv > div:not(:first-child)',
                '.topRightDiv > .ojb_btn:not(:first-child)',
                '.topRightDiv > .roundbox:not(:first-child)'
            ];

            selectors.forEach(selector => {
                this.hideElement(selector);
            });
        }

        applyLayout() {
            document.body.classList.add('cf-simple-mode', 'zoomed');

            const pageContent = document.getElementById('pageContent');
            if (pageContent) {
                pageContent.classList.remove('content-with-sidebar');
                pageContent.classList.add('content-without-sidebar');
            }

            this.hideElement('#sidebar');
            this.hideTopButtons();
        }

        restoreLayout() {
            document.body.classList.remove('cf-simple-mode', 'zoomed');
            document.body.style.transform = '';
            document.body.style.width = '';

            const pageContent = document.getElementById('pageContent');
            if (pageContent) {
                pageContent.classList.add('content-with-sidebar');
                pageContent.classList.remove('content-without-sidebar');
            }

            this.restoreHiddenElements();
        }

        enable() {
            if (this.isActive) return;
            this.createStyle();
            this.applyLayout();
            this.isActive = true;
        }

        disable() {
            if (!this.isActive) return;
            this.removeStyle();
            this.restoreLayout();
            this.isActive = false;
        }

        toggle() {
            if (this.isActive) {
                this.disable();
            } else {
                this.enable();
            }
        }
    }

    function createAutoModeSwitch() {
        const container = document.createElement('span');
        container.style.display = 'flex';
        container.style.alignItems = 'center';
        container.style.marginLeft = '10px';
        container.id = 'cfAutoSimpleSwitch';

        const checkbox = document.createElement('input');
        checkbox.type = 'checkbox';
        checkbox.title = '自动隐藏侧边栏 (Alt+Q快速切换)';
        checkbox.style.width = '18px';
        checkbox.style.height = '18px';
        checkbox.style.cursor = 'pointer';

        checkbox.checked = localStorage.getItem(STORAGE_KEY) === 'on';

        checkbox.addEventListener('change', () => {
            localStorage.setItem(STORAGE_KEY, checkbox.checked ? 'on' : 'off');
        });

        container.appendChild(checkbox);
        return container;
    }

    let simpleMode = new SimpleModeManager();

    function initializeSimpleMode() {
        const checkDOM = setInterval(() => {
            const topRightDiv = document.querySelector('.topRightDiv');
            if (topRightDiv) {
                clearInterval(checkDOM);

                // 只在自动模式开启时初始化简洁模式
                if (localStorage.getItem(STORAGE_KEY) === 'on') {
                    simpleMode.enable();
                }

                // 添加额外检查,确保按钮被隐藏
                setTimeout(() => {
                    if (simpleMode.isActive) {
                        simpleMode.hideTopButtons();
                    }
                }, 500);
            }
        }, 100);
    }

    function setupShortcut() {
        document.addEventListener('keydown', (e) => {
            if (e.altKey && e.key.toLowerCase() === 'q') {
                // 快捷键只临时切换简洁模式,不影响自动模式设置
                simpleMode.toggle();
            }
        });
    }

    function init() {
        const toolbar = document.getElementById('problemToolbar');
        if (toolbar && !document.getElementById('cfAutoSimpleSwitch')) {
            toolbar.appendChild(createAutoModeSwitch());
            setupShortcut();
            initializeSimpleMode();
            return true;
        }
        return false;
    }

    if (!init()) {
        const observer = new MutationObserver(() => {
            if (init()) observer.disconnect();
        });
        observer.observe(document.body, { childList: true, subtree: true });
    }
})();