Mobile Keyboard Spawner

Adds a draggable button that acts as an input to force the mobile keyboard open.Best for opening cheats on mobile.

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey, Greasemonkey of Violentmonkey.

Voor het installeren van scripts heb je een extensie nodig, zoals {tampermonkey_link:Tampermonkey}.

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey of Violentmonkey.

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey of Userscripts.

Voor het installeren van scripts heb je een extensie nodig, zoals {tampermonkey_link:Tampermonkey}.

Voor het installeren van scripts heb je een gebruikersscriptbeheerder nodig.

(Ik heb al een user script manager, laat me het downloaden!)

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

(Ik heb al een beheerder - laat me doorgaan met de installatie!)

// ==UserScript==
// @name         Mobile Keyboard Spawner
// @namespace    https://greasyfork.org/users/Eternosen
// @version      1.2.1
// @description  Adds a draggable button that acts as an input to force the mobile keyboard open.Best for opening cheats on mobile.
// @author       Eternosen
// @match        *://*/*
// @grant        none
// @license      MIT
// @run-at       document-end
// ==/UserScript==

(function() {
    'use strict';

    // PC PROTECTION: Don't show the button on desktop/laptops
    if (!('ontouchstart' in window) && !navigator.maxTouchPoints) return;

    function createKeyboardTrigger() {
        if (document.getElementById('mobile-kb-container')) return;

        const container = document.createElement('div');
        container.id = 'mobile-kb-container';
        (document.body || document.documentElement).appendChild(container);

        const shadow = container.attachShadow({mode: 'open'});

        const input = document.createElement('input');
        input.type = 'text';
        input.value = '⌨️';
        input.setAttribute('autocomplete', 'off');
        input.setAttribute('spellcheck', 'false');
        input.setAttribute('autocorrect', 'off');
        input.setAttribute('autocapitalize', 'none');
        
        input.style = `
            position: fixed; top: 120px; right: 20px;
            width: 50px; height: 50px;
            background: #222; 
            border: 2px solid #444; border-radius: 50%;
            text-align: center; font-size: 24px;
            z-index: 2147483647; cursor: pointer;
            box-shadow: 0 4px 10px rgba(0,0,0,0.5);
            outline: none; touch-action: none;
            caret-color: transparent; color: transparent;
            text-shadow: 0 0 0 white;
            user-select: none; -webkit-user-select: none;
        `;
        shadow.appendChild(input);

        let isDragging = false, startX, startY, xOffset = 0, yOffset = 0;

        input.addEventListener('touchstart', (e) => {
            // Stop page from reacting to the touch start
            e.stopPropagation();
            const touch = e.touches[0];
            startX = touch.clientX - xOffset;
            startY = touch.clientY - yOffset;
            isDragging = false;
        }, {passive: false});

        input.addEventListener('touchmove', (e) => {
            isDragging = true;
            // THE FIX: Stop the page from scrolling while dragging the button
            if (e.cancelable) e.preventDefault();
            e.stopPropagation();
            
            const touch = e.touches[0];
            xOffset = touch.clientX - startX;
            yOffset = touch.clientY - startY;
            input.style.transform = `translate(${xOffset}px, ${yOffset}px)`;
        }, {passive: false});

        input.addEventListener('touchend', (e) => {
            e.stopPropagation();
            if (isDragging) {
                input.blur();
            } else {
                input.value = '';
                input.focus();
            }
        });

        input.addEventListener('blur', () => { input.value = '⌨️'; });

        // BLOCK messy mobile events from leaking to the site
        ['keydown', 'keyup', 'keypress'].forEach(evtType => {
            input.addEventListener(evtType, (e) => { e.stopPropagation(); });
        });

        input.addEventListener('input', (e) => {
            const char = e.data;
            if (!char) return;
            
            let codeVal = 'Unidentified';
            if (/^[a-zA-Z]$/.test(char)) {
                codeVal = `Key${char.toUpperCase()}`;
            } else if (/^[0-9]$/.test(char)) {
                codeVal = `Digit${char}`;
            }

            const keyCode = char.toUpperCase().charCodeAt(0);
            const isUpper = char === char.toUpperCase() && char !== char.toLowerCase();
            
            const eventParams = {
                key: char,
                code: codeVal,
                keyCode: keyCode,
                which: keyCode,
                shiftKey: isUpper,
                ctrlKey: false, altKey: false, metaKey: false,
                bubbles: true, cancelable: true, composed: true,
                view: window
            };

            const down = new KeyboardEvent('keydown', eventParams);
            const press = new KeyboardEvent('keypress', eventParams);
            const up = new KeyboardEvent('keyup', eventParams);

            const target = document.activeElement && document.activeElement !== input 
                           ? document.activeElement 
                           : document.body;

            target.dispatchEvent(down);
            target.dispatchEvent(press);
            target.dispatchEvent(up);

            window.dispatchEvent(down);
            window.dispatchEvent(press);
            window.dispatchEvent(up);
            
            input.value = ''; 
        });
    }

    createKeyboardTrigger();
    
    const observer = new MutationObserver(() => {
        if (!document.getElementById('mobile-kb-container')) createKeyboardTrigger();
    });
    observer.observe(document.documentElement, { childList: true, subtree: true });
})();