Code auf Vollbild erweitern auf der StackExchange-Seite

Vollbild für Code-Blöcke beim Überfahren mit der Maus umschalten

// ==UserScript==
// @name          Expand Code to Fullscreen on StackExchange Site
// @description  Toggle fullscreen for code blocks on hover
// @name:ar      توسيع الكود إلى الشاشة الكاملة على موقع StackExchange
// @description:ar تبديل الشاشة الكاملة لكتل الكود عند التمرير فوقها
// @name:bg      Разширяване на кода до цял екран на сайта StackExchange
// @description:bg Превключване на цял екран за кодови блокове при задържане на курсора
// @name:cs      Rozbalit kód na celou obrazovku na webu StackExchange
// @description:cs Přepínání na celou obrazovku pro bloky kódu při najetí myší
// @name:da      Udrul kode til fuld skærm på StackExchange-siden
// @description:da Skift til fuld skærm for kodeblokke ved at holde musen over
// @name:de      Code auf Vollbild erweitern auf der StackExchange-Seite
// @description:de Vollbild für Code-Blöcke beim Überfahren mit der Maus umschalten
// @name:el      Επέκταση κώδικα σε πλήρη οθόνη στον ιστότοπο StackExchange
// @description:el Εναλλαγή πλήρους οθόνης για μπλοκ κώδικα κατά την αιώρηση
// @name:en      Expand Code to Fullscreen on StackExchange Site
// @description:en Toggle fullscreen for code blocks on hover
// @name:eo      Etendi Kodon al Plenekrano en StackExchange Retejo
// @description:eo Ŝalti plenekranon por kodblokoj dum ŝvebado
// @name:es      Expandir código a pantalla completa en el sitio StackExchange
// @description:es Alternar pantalla completa para bloques de código al pasar el cursor
// @name:fi      Laajenna koodi koko näytölle StackExchange-sivustolla
// @description:fi Vaihda koko näyttö koodilohkoille hiiren ollessa päällä
// @name:fr      Agrandir le code en plein écran sur le site StackExchange
// @description:fr Basculer en plein écran pour les blocs de code au survol
// @name:fr-CA   Agrandir le code en plein écran sur le site StackExchange
// @description:fr-CA Basculer en plein écran pour les blocs de code au survol
// @name:he      הרחב קוד למסך מלא באתר StackExchange
// @description:he החלף למסך מלא עבור בלוקים של קוד בעת ריחוף
// @name:hr      Proširi kod na cijeli zaslon na stranici StackExchange
// @description:hr Prebacivanje na cijeli zaslon za kodne blokove pri prelasku mišem
// @name:hu      Kód kibontása teljes képernyőre a StackExchange oldalon
// @description:hu Teljes képernyőre váltás kódblokkokhoz az egér fölé vitelekor
// @name:id      Perluas Kode ke Layar Penuh di Situs StackExchange
// @description:id Alihkan layar penuh untuk blok kode saat mengarahkan kursor
// @name:it      Espandi il codice a schermo intero sul sito StackExchange
// @description:it Attiva/disattiva lo schermo intero per i blocchi di codice al passaggio del mouse
// @name:ja      StackExchangeサイトでコードをフルスクリーンに展開
// @description:ja ホバー時にコードブロックをフルスクリーンに切り替えます
// @name:ka      გააფართოვეთ კოდი სრულ ეკრანზე StackExchange საიტზე
// @description:ka გადართეთ სრულ ეკრანზე კოდის ბლოკებისთვის მაუსის გადატარებისას
// @name:ko      StackExchange 사이트에서 코드를 전체 화면으로 확장
// @description:ko 마우스를 올리면 코드 블록을 전체 화면으로 전환
// @name:nb      Utvid kode til fullskjerm på StackExchange-siden
// @description:nb Veksle til fullskjerm for kodeblokker ved å holde musepekeren over
// @name:nl      Code uitbreiden naar volledig scherm op StackExchange-site
// @description:nl Schakel naar volledig scherm voor codeblokken bij zweven
// @name:pl      Rozwiń kod na pełny ekran na stronie StackExchange
// @description:pl Przełącz na pełny ekran dla bloków kodu przy najechaniu kursorem
// @name:pt-BR   Expandir código para tela cheia no site StackExchange
// @description:pt-BR Alternar tela cheia para blocos de código ao passar o mouse
// @name:ro      Extinde codul la ecran complet pe site-ul StackExchange
// @description:ro Comută pe ecran complet pentru blocurile de cod la trecerea cursorului
// @name:ru      Развернуть код на полный экран на сайте StackExchange
// @description:ru Переключить полноэкранный режим для блоков кода при наведении
// @name:sk      Rozbaliť kód na celú obrazovku na stránke StackExchange
// @description:sk Prepínať na celú obrazovku pre bloky kódu pri prechode myšou
// @name:sr      Прошири код на цео екран на сајту StackExchange
// @description:sr Пребаци на цео екран за блокове кода при преласку мишем
// @name:sv      Utöka kod till helskärm på StackExchange-sidan
// @description:sv Växla till helskärm för kodblock vid hovring
// @name:th      ขยายโค้ดเป็นเต็มหน้าจอบนเว็บไซต์ StackExchange
// @description:th สลับไปยังเต็มหน้าจอสำหรับบล็อกโค้ดเมื่อวางเมาส์ไว้เหนือ
// @name:tr      StackExchange Sitesinde Kodu Tam Ekran Yap
// @description:tr Üzerine gelindiğinde kod blokları için tam ekranı aç/kapat
// @name:ug      StackExchange تور بېتىدە كودنى تولۇق ئېكرانغا كېڭەيتىش
// @description:ug چاشقاننى يۆتكەپ ئۆتكەندە كود بۆلەكلىرى ئۈچۈن تولۇق ئېكراننى ئالماشتۇرۇش
// @name:uk      Розгорнути код на весь екран на сайті StackExchange
// @description:uk Перемикати повноекранний режим для блоків коду при наведенні
// @name:vi      Mở rộng mã sang toàn màn hình trên trang StackExchange
// @description:vi Chuyển đổi toàn màn hình cho các khối mã khi di chuột qua
// @name:zh      在 StackExchange 网站上将代码扩展到全屏
// @description:zh 悬停时切换代码块的全屏模式
// @name:zh-CN   在 StackExchange 网站上将代码扩展到全屏
// @description:zh-CN 悬停时切换代码块的全屏模式
// @name:zh-HK   喺 StackExchange 網站上將程式碼擴展到全螢幕
// @description:zh-HK 喺滑鼠懸停時切換程式碼區塊嘅全螢幕模式
// @name:zh-SG   在 StackExchange 网站上将代码扩展到全屏
// @description:zh-SG 悬停时切换代码块的全屏模式
// @name:zh-TW   在 StackExchange 網站上將程式碼擴展至全螢幕
// @description:zh-TW 懸停時切換程式碼區塊的全螢幕模式
// @namespace    http://tampermonkey.net/
// @author      aspen138
// @version      0.1.3.1
// @match      *://*.stackexchange.com/*
// @match          *://*.stackoverflow.com/questions/*
// @match          *://superuser.com/questions/*
// @match          *://meta.superuser.com/questions/*
// @match          *://serverfault.com/questions/*
// @match          *://meta.serverfault.com/questions/*
// @match          *://askubuntu.com/questions/*
// @match          *://meta.askubuntu.com/questions/*
// @match          *://mathoverflow.net/questions/*
// @match          *://meta.mathoverflow.net/questions/*
// @match          *://*.stackexchange.com/questions/*
// @match          *://answers.onstartups.com/questions/*
// @match          *://meta.answers.onstartups.com/questions/*
// @match          *://stackapps.com/questions/*
// @match          *://*.stackoverflow.com/review/*
// @match          *://superuser.com/review/*
// @match          *://meta.superuser.com/review/*
// @match          *://serverfault.com/review/*
// @match          *://meta.serverfault.com/review/*
// @match          *://askubuntu.com/review/*
// @match          *://meta.askubuntu.com/review/*
// @match          *://mathoverflow.net/review/*
// @match          *://meta.mathoverflow.net/review/*
// @match          *://*.stackexchange.com/review/*
// @match          *://answers.onstartups.com/review/*
// @match          *://meta.answers.onstartups.com/review/*
// @match          *://stackapps.com/review/*
// @match          *://*.stackoverflow.com/search*
// @match          *://superuser.com/search*
// @match          *://meta.superuser.com/search*
// @match          *://serverfault.com/search*
// @match          *://meta.serverfault.com/search*
// @match          *://askubuntu.com/search*
// @match          *://meta.askubuntu.com/search*
// @match          *://mathoverflow.net/search*
// @match          *://meta.mathoverflow.net/search*
// @match          *://*.stackexchange.com/search*
// @match          *://answers.onstartups.com/search*
// @match          *://meta.answers.onstartups.com/search*
// @match          *://stackapps.com/search*
// @grant        none
// @license    MIT
// ==/UserScript==



function Toast(msg, duration) {
    let p1 = new Promise((resolve,reject)=>{
        duration = isNaN(duration) ? 3000 : duration;
        var m = document.createElement('div');
        m.innerHTML = msg;
        m.style.cssText = "font-family:siyuan;max-width:60%;min-width: 150px;padding:0 14px;height: 40px;color: rgb(255, 255, 255);line-height: 40px;text-align: center;border-radius: 4px;position: fixed;top: 50%;left: 50%;transform: translate(-50%, -50%);z-index: 999999;background: rgba(0, 0, 0,.7);font-size: 16px;";
        document.body.appendChild(m);
        setTimeout(function() {
            var d = 0.5;
            m.style.webkitTransition = '-webkit-transform ' + d + 's ease-in, opacity ' + d + 's ease-in';
            m.style.opacity = '0';
            setTimeout(function() {
                document.body.removeChild(m)
            }, d * 1000);
        }, duration);
    });
}



(function() {
    'use strict';

    // Function to inject styles
    function addStyles() {
        const style = document.createElement('style');
        style.type = 'text/css';
        style.innerHTML = `
            .code-wrapper {
                position: relative;
            }
            .button {
                position: absolute;
                top: 0;
                z-index: 10;
                padding: 4px 8px;
                background-color: #eee;
                border: none;
                cursor: pointer;
                border-radius: 4px;
                font-size: 12px;
                display: none;
            }
            .fullscreen-btn {
                right: 0;
            }
            .copy-btn {
                right: 80px; /* Adjust based on the size of the fullscreen button */
            }
            .button:hover {
                background-color: #ddd;
            }
            .code-wrapper:hover .button {
                display: block;
            }
            .code-wrapper.fullscreen {
                background: white;
                color: black;
                width: 100%;
                height: 100%;
                overflow: auto;
                margin: 0;
                padding: 20px;
            }
            .code-wrapper.fullscreen .hljs {
                display: block;
                overflow-x: auto;
                padding: 0.5em;
                color: inherit;
                background: inherit;
            }
        `;
        document.head.appendChild(style);
    }

    // Function to toggle fullscreen for the specific code block
    function toggleFullScreen(codeWrapper) {
        if (!document.fullscreenElement && codeWrapper.requestFullscreen) {
            codeWrapper.requestFullscreen().then(() => {
                codeWrapper.classList.add('fullscreen');
                codeWrapper.querySelector('code').classList.forEach(cls => {
                    codeWrapper.classList.add(cls);
                });
            });
        } else if (document.fullscreenElement && document.exitFullscreen) {
            document.exitFullscreen().then(() => {
                codeWrapper.classList.remove('fullscreen');
                codeWrapper.querySelector('code').classList.forEach(cls => {
                    codeWrapper.classList.remove(cls);
                });
            });
        }
    }

    // Function to copy code to clipboard
    function copyToClipboard(codeWrapper) {
        const code = codeWrapper.querySelector('code').innerText;
        navigator.clipboard.writeText(code).then(() => {
            console.log('Code copied to clipboard!');
            Toast("Code copied to clipboard!", 100);

            // codeWrapper.textContent="Copied";
            // setTimeout( ()=>copyBtn.textContent="Copy", 1*1000);

        }).catch(err => {
            console.error('Error copying code to clipboard: ', err);
        });
    }

    // Function to create fullscreen and copy buttons for each code block
    function addButtons() {
        document.querySelectorAll('pre code').forEach((code) => {
            let wrapper = code.closest('.code-wrapper');
            if (!wrapper) {
                wrapper = document.createElement('div');
                wrapper.classList.add('code-wrapper');
                code.classList.forEach(cls => {
                    if (cls !== 'hljs') {
                        wrapper.classList.add(cls);
                    }
                });
                code.parentNode.insertBefore(wrapper, code);
                wrapper.appendChild(code);
            }

            if (!wrapper.querySelector('.fullscreen-btn')) {
                const fullscreenBtn = document.createElement('button');
                fullscreenBtn.textContent = 'Fullscreen';
                fullscreenBtn.classList.add('fullscreen-btn', 'button');
                fullscreenBtn.addEventListener('click', () => toggleFullScreen(wrapper));
                wrapper.appendChild(fullscreenBtn);
            }

            // Add copy button
            if (!wrapper.querySelector('.copy-btn')) {
                const copyBtn = document.createElement('button');
                copyBtn.textContent = 'Copy';
                copyBtn.classList.add('copy-btn', 'button');
                copyBtn.addEventListener('click', () => copyToClipboard(wrapper));
                wrapper.appendChild(copyBtn);
            }
        });
    }

    // Wait for the DOM to be fully loaded
    window.addEventListener('load', function() {
        addStyles();
        setTimeout(addButtons, 0);
    });
})();