Console-in-Pages

Creates a floating console in browser

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         Console-in-Pages
// @namespace    http://tampermonkey.net/
// @version      1.0.0
// @description  Creates a floating console in browser
// @author       You
// @match        *://*/*
// @grant        none
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    // Create the shell container
    const shellContainer = document.createElement('div');
    shellContainer.style.position = 'fixed';
    shellContainer.style.bottom = '100px';
    shellContainer.style.left = '20px';
    shellContainer.style.width = '500px';
    shellContainer.style.height = '300px';
    shellContainer.style.backgroundColor = '#000';
    shellContainer.style.color = '#0f0';
    shellContainer.style.fontFamily = 'monospace';
    shellContainer.style.zIndex = '99999';
    shellContainer.style.overflowY = 'auto';
    shellContainer.style.padding = '10px';
    shellContainer.style.display = 'none';  // Initially hidden
    document.body.appendChild(shellContainer);

    // Create the header (for dragging)
    const header = document.createElement('div');
    header.style.backgroundColor = '#333';
    header.style.padding = '5px';
    header.style.cursor = 'move';
    header.innerText = 'Tampermonkey generated Console';
    shellContainer.appendChild(header);

    // Create input field for commands
    const inputField = document.createElement('input');
    inputField.style.width = '100%';
    inputField.style.backgroundColor = '#000';
    inputField.style.color = '#0f0';
    inputField.style.border = 'none';
    inputField.style.outline = 'none';
    inputField.style.fontSize = '16px';
    inputField.placeholder = 'Type your command here...';
    shellContainer.appendChild(inputField);

    // Function to handle user input
    inputField.addEventListener('keydown', function(e) {
        if (e.key === 'Enter') {
            const command = inputField.value.trim();
            if (command) {
                executeCommand(command);
            }
            inputField.value = ''; // Clear input after execution
        }
    });

    // Function to execute commands
    function executeCommand(command) {
        const output = document.createElement('div');
        output.textContent = `$ ${command}`;
        shellContainer.appendChild(output);

        // Handle predefined commands
        if (command === 'hello') {
            showOutput('Hello world!');
        } else if (command === 'date') {
            showOutput(new Date().toLocaleString());
        } else if (command === 'clear') {
            clearShell();
        } else {
            showOutput('Command not recognized');
        }

        // Scroll to bottom
        shellContainer.scrollTop = shellContainer.scrollHeight;
    }

    // Function to display command output
    function showOutput(outputText) {
        const output = document.createElement('div');
        output.textContent = outputText;
        shellContainer.appendChild(output);
    }

    // Function to clear the shell
    function clearShell() {
        shellContainer.innerHTML = '';
        shellContainer.appendChild(header); // Keep the header
        shellContainer.appendChild(inputField); // Keep the input field
    }

    // Create the resize handle
    const resizeHandle = document.createElement('div');
    resizeHandle.style.position = 'absolute';
    resizeHandle.style.bottom = '0';
    resizeHandle.style.right = '0';
    resizeHandle.style.width = '20px';
    resizeHandle.style.height = '20px';
    resizeHandle.style.backgroundColor = '#0f0';
    resizeHandle.style.cursor = 'se-resize';
    shellContainer.appendChild(resizeHandle);

    // Drag functionality for the terminal window
    let isDragging = false;
    let offsetX, offsetY;

    header.addEventListener('mousedown', function(e) {
        isDragging = true;
        offsetX = e.clientX - shellContainer.getBoundingClientRect().left;
        offsetY = e.clientY - shellContainer.getBoundingClientRect().top;
        document.addEventListener('mousemove', dragShell);
        document.addEventListener('mouseup', stopDrag);
    });

    function dragShell(e) {
        if (isDragging) {
            shellContainer.style.left = `${e.clientX - offsetX}px`;
            shellContainer.style.top = `${e.clientY - offsetY}px`;
        }
    }

    function stopDrag() {
        isDragging = false;
        document.removeEventListener('mousemove', dragShell);
        document.removeEventListener('mouseup', stopDrag);
    }

    // Resize functionality for the terminal window
    let isResizing = false;
    let initialWidth, initialHeight, initialMouseX, initialMouseY;

    resizeHandle.addEventListener('mousedown', function(e) {
        isResizing = true;
        initialWidth = shellContainer.offsetWidth;
        initialHeight = shellContainer.offsetHeight;
        initialMouseX = e.clientX;
        initialMouseY = e.clientY;
        document.addEventListener('mousemove', resizeShell);
        document.addEventListener('mouseup', stopResize);
    });

    function resizeShell(e) {
        if (isResizing) {
            const width = initialWidth + (e.clientX - initialMouseX);
            const height = initialHeight + (e.clientY - initialMouseY);
            shellContainer.style.width = `${width}px`;
            shellContainer.style.height = `${height}px`;
        }
    }

    function stopResize() {
        isResizing = false;
        document.removeEventListener('mousemove', resizeShell);
        document.removeEventListener('mouseup', stopResize);
    }

    // Create the toggle icon
    const toggleIcon = document.createElement('div');
    toggleIcon.style.position = 'fixed';
    toggleIcon.style.bottom = '60px';
    toggleIcon.style.left = '10px';
    toggleIcon.style.width = '40px';
    toggleIcon.style.height = '40px';
    toggleIcon.style.backgroundColor = '#0f0';
    toggleIcon.style.color = '#000';
    toggleIcon.style.fontSize = '24px';
    toggleIcon.style.borderRadius = '50%';
    toggleIcon.style.textAlign = 'center';
    toggleIcon.style.lineHeight = '40px';
    toggleIcon.style.cursor = 'pointer';
    toggleIcon.style.zIndex = '100000';
    toggleIcon.innerHTML = '⌨'; // Unicode for a refresh icon (can be replaced with other symbols)
    document.body.appendChild(toggleIcon);

    // Add dragging functionality to the toggle icon
    let iconIsDragging = false;
    let iconOffsetX, iconOffsetY;
    let iconDragStartTime;

    toggleIcon.addEventListener('mousedown', function(e) {
        iconIsDragging = false;
        iconDragStartTime = Date.now(); // Record when the drag starts
        iconOffsetX = e.clientX - toggleIcon.getBoundingClientRect().left;
        iconOffsetY = e.clientY - toggleIcon.getBoundingClientRect().top;
        document.addEventListener('mousemove', dragIcon);
        document.addEventListener('mouseup', stopIconDrag);
    });

    function dragIcon(e) {
        iconIsDragging = true;
        toggleIcon.style.left = `${e.clientX - iconOffsetX}px`;
        toggleIcon.style.top = `${e.clientY - iconOffsetY}px`;
    }

    function stopIconDrag(e) {
        document.removeEventListener('mousemove', dragIcon);
        document.removeEventListener('mouseup', stopIconDrag);

        // If the mouse was held down for less than 300ms and moved less than 5px, consider it a click
        if (iconIsDragging && (Date.now() - iconDragStartTime > 300 || Math.abs(e.clientX - toggleIcon.offsetLeft) > 5 || Math.abs(e.clientY - toggleIcon.offsetTop) > 5)) {
            iconIsDragging = false;  // It was a drag, not a click
        } else {
            // Toggle the terminal visibility only on click
            if (shellContainer.style.display === 'none') {
                shellContainer.style.display = 'block';
            } else {
                shellContainer.style.display = 'none';
            }
        }
    }

})();