Show Console Messages

Show console messages (such as console.log, console.error ...) on screen

目前为 2024-09-10 提交的版本。查看 最新版本

// ==UserScript==
// @name        Show Console Messages
// @namespace   Kyan Violentmonkey Scripts
// @match       *://*/*
// @grant       none
// @license     MIT
// @version     1.1.12
// @author      Kyan
// @description Show console messages (such as console.log, console.error ...) on screen
// ==/UserScript==
;(function () {
    'use strict';

    // CSS styles
    let console_msg_styles = document.createElement('style');
    console_msg_styles.innerHTML = `
        .console-message-div {
            position: fixed;
            z-index: 999;
            bottom: 2em;
            right: 2em;
            background: transparent;
            display: flex;
            flex-wrap: wrap;
            flex-direction: column-reverse;
            transition: all 1s ease-out;  /* for slide_show() */
            overflow: hidden;  /* for slide_show() */
            pointer-events: none;
        }
        .console-message-wrapper {
            width: 100%;
            background: transparent;
            transition: all 1s ease-out;
            position: relative;
            pointer-events: none;
        }
        .console-message-wrapper-progress-bar {
            position: absolute;
            bottom: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background-color: transparent;
            border-radius: 5px;
            z-index: -1;
            overflow: hidden;  /* hide border-radius of .console-message-wrapper-progress */
        }
        .console-message-wrapper-progress {
            height: 100%;
            background-color: rgba(94, 129, 172, 0.25);  /* nord10 Frost (Darkest) */
            width: 100%;
            transition: all 1s linear;
            transform-origin: right;
        }
        .console-message-text {
            float: right;
            padding: 5px;
            margin: 5px;
            border-radius: 5px;
            width: fit-content;
            font-size: 15px;
            transition: all 1s ease-out;
            white-space: pre-wrap;  /* Preserve whitespace but allow wrapping */
            word-break: break-word;  /* Break long words */
            max-width: 62vw;
            pointer-events: auto;
            text-shadow: 0px 0px 5px #2e3440;  /* nord0 Polar Night (Darkest) */
        }
        .cursor-pointer {
            cursor: pointer;
        }
        .bg-glass {
            backdrop-filter: blur(5px);
        }
    `;
    document.head.appendChild(console_msg_styles);

    // create a div to show console log
    let console_msg_div = document.createElement('div');
    console_msg_div.classList.add('console-message-div');
    document.body.appendChild(console_msg_div);


    // override the default console.log function
    let original_console_log = console.log;
    let original_console_error = console.error;
    let original_console_warn = console.warn;
    let original_console_info = console.info;
    let original_console_debug = console.debug;

    const exit_to_right = (ele) => {
        if (typeof ele !== 'undefined') {
            ele.style.opacity = 0;
            ele.style.transform = 'translateX(200%)';
            setTimeout(() => ele.remove(), 1000);
        }
    }
    const slide_show = (ele) => {
        if (typeof ele !== 'undefined') {
          let ele_height = window.getComputedStyle(ele).height  // Get real height (including padding)
          ele.style.height = '0'  // Init height with 0px
          ele.offsetHeight  // Trigger a browser repaint and force reflow to ensure the height of 0px is calculated
          ele.style.height = ele_height  // Recover element height
        }
    }

    const console_call = (type, original_function, message) => {
        original_function(message)
        if (message === 'bl') {
            return;
        }
        if (typeof message === 'object' && message !== null) {
            message = JSON.stringify(message, null, 4)  // No replacing, 4 spaces for indent
        }
        let msglet_wrapper = document.createElement('div');
        msglet_wrapper.classList.add('console-message-wrapper');
        let msglet = document.createElement('div');
        msglet.classList.add('console-message-text');
        msglet.classList.add('bg-glass');
        msglet.classList.add('cursor-pointer')
        msglet.addEventListener('click', () => exit_to_right(msglet_wrapper))
        let flair = ''
        let transparency = 0.618
        switch (type) {
            case 'log':
                flair = '💡';
                msglet.style.color = 'white';  //
                msglet.style.backgroundColor = `rgba(46, 52, 64, ${transparency})`;  // nord0 Polar Night (Darkest)
                break;
            case 'error':
                flair = '❌';
                msglet.style.color = 'white';
                msglet.style.backgroundColor = `rgba(191, 97, 106, ${transparency})`;  // nord11 Aurora (Red)
                break;
            case 'warn':
                flair = '⚠️';
                msglet.style.color = '#EBCB8B';  // nord13 Aurora (Yellow)
                msglet.style.backgroundColor = `rgba(46, 52, 64, ${transparency})`;
                break;
            case 'info':
                flair = 'ℹ️';
                msglet.style.color = 'white';
                msglet.style.backgroundColor = `rgba(163, 190, 140, ${transparency})`;  // nord14 Aurora (Green)
                break;
            case 'debug':
                flair = '🐛';
                msglet.style.color = 'white';
                msglet.style.backgroundColor = `rgba(180, 142, 173, ${transparency})`;  // nord15 Aurora (Purple)
                break;
            default:
                flair = `[${type}]`;
                msglet.style.color = '#ECEFF4';  // nord6 Snow Storm (Lightest)
                msglet.style.backgroundColor = `rgba(46, 52, 64, ${transparency})`;  // nord0 Polar Night (Darkest)
                break;
        }
        if (type == 'error' && typeof message !== "string") {
            console.error(message.message)
            let err_dom = new DOMParser().parseFromString(message.error, "text/xml")
            let err_dom_msg = err_dom.querySelector("Message")
            if (err_dom_msg !== null) {
                console.error(err_dom_msg.innerHTML)
            }
            let err_dom_dtl = err_dom.querySelector("Details")
            if (err_dom_dtl !== null) {
                console.error(err_dom_dtl.innerHTML)
            }
        } else {
            // msglet.innerHTML = flair + ' ' + bionic_reading(message);
            msglet.innerHTML = flair + ' ' + message
        }
        msglet_wrapper.appendChild(msglet);
        console_msg_div.prepend(msglet_wrapper);
        slide_show(msglet_wrapper)
        // Calculate the time left of the message
        let lifespan = Math.max(1000 + message.length * 100, 2500)
        // Generate a progress bar
        let progress_bar = document.createElement('div');
        progress_bar.classList.add('console-message-wrapper-progress-bar');
        let progress = document.createElement('div');
        progress.classList.add('console-message-wrapper-progress');
        progress_bar.appendChild(progress);
        msglet.appendChild(progress_bar);
        progress.style.transitionDuration = lifespan + 'ms';
        // Animate the progress bar
        setTimeout(() => {
            progress.style.transform = 'scaleX(0)'
        }, 100);
        // Easeout the message after few seconds
        progress.addEventListener('transitionend', () => {
            if (progress.style.transform === 'scaleX(0)') {
                exit_to_right(msglet_wrapper)
            }
        })
    }

    // Monkey Patch
    console.log = (message) => console_call('log', original_console_log, message)
    console.error = (message) => console_call('error', original_console_error, message)
    console.warn = (message) => console_call('warn', original_console_warn, message)
    console.info = (message) => console_call('info', original_console_info, message)
    console.debug = (message) => console_call('debug', original_console_debug, message)
})();

const bionic_reading = (str) => {
    let bionified = '';
    for (let word of str.split(' ')) {
        if (word.length == 2) {
            bionified += `<b>${word[0]}</b>${word[1]}`
        } else if (word.length > 2) {
            bionified += `<b>${word.slice(0, 2)}</b>${word.slice(2)}`
        } else {
            bionified += word
        }
        bionified += ' '
    }
    return bionified.trim()
}

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址