- 
            
      
        
      
    Star
      
          
          (184)
      
  
You must be signed in to star a gist 
- 
              
      
        
      
    Fork
      
          
          (45)
      
  
You must be signed in to fork a gist 
- 
      
- 
        Save amunchet/4cfaf0274f3d238946f9f8f94fa9ee02 to your computer and use it in GitHub Desktop. 
| // ==UserScript== | |
| // @name noVNC Paste for Proxmox | |
| // @namespace http://tampermonkey.net/ | |
| // @version 0.2a | |
| // @description Pastes text into a noVNC window (for use with Proxmox specifically) | |
| // @author Chester Enright | |
| // @match https://* | |
| // @include /^.*novnc.*/ | |
| // @require http://code.jquery.com/jquery-3.3.1.min.js | |
| // @grant none | |
| // ==/UserScript== | |
| const delay = 1 | |
| ;(function () { | |
| 'use strict' | |
| window.sendString = function(text) { | |
| var el = document.getElementById("canvas-id") | |
| text.split("").forEach(x=>{ | |
| setTimeout(()=>{ | |
| var needs_shift = x.match(/[A-Z!@#$%^&*()_+{}:\"<>?~|]/) | |
| let evt | |
| if (needs_shift) { | |
| evt = new KeyboardEvent("keydown", {keyCode: 16}) | |
| el.dispatchEvent(evt) | |
| evt = new KeyboardEvent("keydown", {key: x, shiftKey: true}) | |
| el.dispatchEvent(evt) | |
| evt = new KeyboardEvent("keyup", {keyCode: 16}) | |
| el.dispatchEvent(evt) | |
| }else{ | |
| evt = new KeyboardEvent("keydown", {key: x}) | |
| } | |
| el.dispatchEvent(evt) | |
| }, delay) | |
| }) | |
| } | |
| $(document).ready(function() { | |
| setTimeout(()=>{ | |
| console.log("Starting up noVNC Copy/Paste (for Proxmox)") | |
| $("canvas").attr("id", "canvas-id") | |
| $("canvas").on("mousedown", (e)=>{ | |
| if(e.button == 2){ // Right Click | |
| navigator.clipboard.readText().then(text =>{ | |
| window.sendString(text) | |
| }) | |
| } | |
| }) | |
| }, 1000); | |
| }) | |
| })() | 
it worked, thank you <3
Is anyone else having a problem with carriage returns? I have a multi-line copy that is pasted into one line on Proxmox. Sometimes, the leading character of the next line is omitted, too.
@Laz2047 I would try the version above by @zakhar-kogan - it might handle carriage returns a bit better (I haven't actually tried it myself). The original version was just meant to paste in long passwords or single line items, so I didn't really consider multi-lines.
Thank you. I'll check it out.
@amunchet Just came here to say I love you for making this script. It's such a massive quality of life improvement!
used this in console to paste ssh key using right mouse click.
(function () {
    const delay = 50; // Slow down typing to avoid missed characters
    function loadjQuery(callback) {
        if (typeof window.jQuery !== 'undefined') {
            callback(window.jQuery);
        } else {
            const script = document.createElement('script');
            script.src = "https://code.jquery.com/jquery-3.3.1.min.js";
            script.onload = () => callback(window.jQuery);
            document.head.appendChild(script);
        }
    }
    function sendChar(el, char) {
        if (char === '\n' || char === '\r') {
            // Handle Enter
            el.dispatchEvent(new KeyboardEvent("keydown", { key: "Enter", code: "Enter", which: 13, keyCode: 13 }));
            el.dispatchEvent(new KeyboardEvent("keyup", { key: "Enter", code: "Enter", which: 13, keyCode: 13 }));
            return;
        }
        const needsShift = char.match(/[A-Z!@#$%^&*()_+{}:"<>?~|]/);
        if (needsShift) {
            el.dispatchEvent(new KeyboardEvent("keydown", { key: "Shift", code: "ShiftLeft", shiftKey: true }));
        }
        el.dispatchEvent(new KeyboardEvent("keydown", { key: char, code: undefined, shiftKey: !!needsShift }));
        el.dispatchEvent(new KeyboardEvent("keyup", { key: char, code: undefined, shiftKey: !!needsShift }));
        if (needsShift) {
            el.dispatchEvent(new KeyboardEvent("keyup", { key: "Shift", code: "ShiftLeft", shiftKey: false }));
        }
    }
    function sendString(text) {
        const el = document.getElementById("canvas-id");
        if (!el) {
            console.warn("Canvas not found");
            return;
        }
        text.split("").forEach((char, i) => {
            setTimeout(() => sendChar(el, char), delay * i);
        });
    }
    loadjQuery(($) => {
        setTimeout(() => {
            console.log("noVNC Paste active");
            $("canvas").attr("id", "canvas-id");
            $("canvas").on("mousedown", (e) => {
                if (e.button === 2) { // Right-click
                    navigator.clipboard.readText().then(text => {
                        sendString(text);
                    });
                }
            });
        }, 1000);
    });
})();
The canvas finding logic is broken, use this for sendString() if you're using novnc and it'll work:
function sendString(text) {
        var el = document.querySelector("#noVNC_container canvas")
        text.split("").forEach(x=>{
            setTimeout(()=>{
                 var needs_shift = x.match(/[A-Z!@#$%^&*()_+{}:\"<>?~|]/)
                 let evt
                 if (needs_shift) {
                     evt = new KeyboardEvent("keydown", {keyCode: 16})
                     el.dispatchEvent(evt)
                     evt = new KeyboardEvent("keydown", {key: x, shiftKey: true})
                     el.dispatchEvent(evt)
                     evt = new KeyboardEvent("keyup", {keyCode: 16})
                     el.dispatchEvent(evt)
                 }else{
                     evt = new KeyboardEvent("keydown", {key: x})
                }
                el.dispatchEvent(evt)
            }, 100)
        })
    }
Forked and updated it for German Mac Keyboard.
Added Async writing to be able to paste walls of text.
Tried many mapping variants, but mapping the whole keyboard worked best.
https://gist.github.com/JonasKrausch/3c64e4ca9f4a9bdde66a91759f24e574