Skip to content

Instantly share code, notes, and snippets.

@stil
Last active January 23, 2025 14:42
Show Gist options
  • Save stil/54052d846c9e77e9da4f79af4c831bf5 to your computer and use it in GitHub Desktop.
Save stil/54052d846c9e77e9da4f79af4c831bf5 to your computer and use it in GitHub Desktop.
Auto type in noVNC (Proxmox)
(async () => {
const text = prompt("Enter text to type:");
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
const input = document.getElementById("noVNC_keyboardinput");
const keydown = (key) => input.dispatchEvent(new KeyboardEvent("keydown", { key }));
for (let i = 0; i < text.length; i++) { keydown(text[i]); await sleep(50); }
})();
@stil
Copy link
Author

stil commented Jun 29, 2024

In Firefox:

  • Click on Hamburger button to break out from VNC focus
  • Ctrl + Shift + I to open web console
  • Paste the code and confirm
  • You'll be prompted for text to type, confirm

@stil
Copy link
Author

stil commented Sep 26, 2024

This macro autotypes text, fires Tab twice and autotypes same text again. Useful for Debian 12 installer user account passwords.

(async () => {
  const text = prompt("Enter text to type:");
  const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
  const input = document.getElementById("noVNC_keyboardinput");
  const keydown = (key) => input.dispatchEvent(new KeyboardEvent("keydown", { key }));
  const sequence = [...text.split(''), 'Tab', 'Tab', ...text.split('')];
  for (let i = 0; i < sequence.length; i++) { keydown(sequence [i]); await sleep(50); }
})();

@rmb122
Copy link

rmb122 commented Oct 18, 2024

By integrating the functionality from https://github.com/aggregate1166877/noVNC-Paste-Tool/blob/primary/paste-tool.js, now we can paste text through a nice GUI.😎

(function() {
  var input = '';
  var delay = '100';
  var index = -1;

  var mainDivId = '00novnccustompastetool0947-maindiv';
  var textId = '00novnccustompastetool0947-textinput';
  var numId = '00novnccustompastetool0947-numinput';


  function updateUserInput(event) {
    event.preventDefault();
  }

  function paste(event) {
    event.preventDefault();
    var userInput = document.getElementById(textId);
    input = userInput.value;

    var userNumInput = document.getElementById(numId);
    delay = Number(userNumInput.value);
    if (!delay) {
      alert('Cannot proceed: delay number is invalid.');
      return close();
    }

    close(event);
    setTimeout(tick, 500);
  }

  function close(event) {
    event.preventDefault();
    var mainDiv = document.getElementById(mainDivId);
    document.body.removeChild(mainDiv);
  }

  function showGui() {
    var div = document.createElement('div');
    div.id = mainDivId;
    div.style.position = 'fixed';
    div.style.zIndex = '9999999999';
    div.style.backgroundColor = 'rgb(221 221 221 / 90%)';
    div.style.top = '0';
    div.style.left = '0';
    div.style.right = '0';
    div.style.padding = '8px';
    div.style.height = '168px';

    div.innerHTML = '<b>Paste your text</b><br>' +
      'Note: Use your mouse for copying and pasting because the KVM console ' +
      'snatches all input and this is the only sane work-around.' +
      '<br>';

    var textInput = document.createElement('textarea');
    textInput.id = textId;
    textInput.onkeydown = updateUserInput;
    textInput.style.display = 'block';
    textInput.style.width = '100%';
    textInput.style.marginBottom = '8px';

    var inputDesc = document.createElement('label');
    inputDesc.innerHTML = 'Per-key delay in ms:&nbsp;';
    inputDesc.title = 'Sending keys too fast can cause issues (such as ' +
      'skipped keys); the delay helps alleviate this.';

    var numInput = document.createElement('input');
    numInput.title = inputDesc.title;
    numInput.setAttribute('type', 'number');
    numInput.setAttribute('min', '1');
    numInput.setAttribute('max', '100000');
    numInput.value = delay;
    numInput.id = numId;

    var ok = document.createElement('button');
    ok.innerText = 'Paste';
    ok.onclick = paste;
    ok.style.margin = '8px';

    var cancel = document.createElement('button');
    cancel.innerText = 'Cancel';
    cancel.onclick = close;

    div.append(textInput);
    div.append(inputDesc);
    div.append(numInput);
    div.append(document.createElement('br'));
    div.append(cancel);
    div.append(ok);

    document.body.append(div);
  }

  const noVNCinput = document.querySelector('iframe').contentDocument.getElementById("noVNC_keyboardinput");
  const keydown = (key) => noVNCinput.dispatchEvent(new KeyboardEvent("keydown", { key }));

  function encodeAndSendKey(character) {
    if (character === '\r') {
      return;
    }
    if (character === '\t') {
      keydown("Tab");
      return;
    }
    if (character === '\n') {
      keydown("Enter");
      return;
    }
    keydown(character);
  }

  function tick() {
    if (++index >= input.length) {
      return;
    }

    encodeAndSendKey(input[index]);
    setTimeout(tick, delay);
  }

  showGui();
})();

@rallisf1
Copy link

Here's a minified bookmarklet based on @rmb122 's answer

javascript:(function(){var e,t,n,a,i,l,o="",r="100",s=-1,p="00novnccustompastetool0947-maindiv",u="00novnccustompastetool0947-textinput",d="00novnccustompastetool0947-numinput";function c(e){e.preventDefault();var t=document.getElementById(p);document.body.removeChild(t)}let y=document.querySelector("iframe").contentDocument.getElementById("noVNC_keyboardinput"),m=e=>y.dispatchEvent(new KeyboardEvent("keydown",{key:e}));function $(){!(++s>=o.length)&&(!function e(t){if("\r"!==t){if(""===t){m("Tab");return}if("\n"===t){m("Enter");return}m(t)}}(o[s]),setTimeout($,r))}(e=document.createElement("div")).id=p,e.style.position="fixed",e.style.zIndex="9999999999",e.style.backgroundColor="rgb(221 221 221 / 90%)",e.style.top="0",e.style.left="0",e.style.right="0",e.style.padding="8px",e.style.height="168px",e.innerHTML="<b>Paste your text</b><br>Note: Use your mouse for copying and pasting because the KVM console snatches all input and this is the only sane work-around.<br>",(t=document.createElement("textarea")).id=u,t.onkeydown=function e(t){t.preventDefault()},t.style.display="block",t.style.width="100%",t.style.marginBottom="8px",(n=document.createElement("label")).innerHTML="Per-key delay in ms:&nbsp;",n.title="Sending keys too fast can cause issues (such as skipped keys); the delay helps alleviate this.",(a=document.createElement("input")).title=n.title,a.setAttribute("type","number"),a.setAttribute("min","1"),a.setAttribute("max","100000"),a.value=r,a.id=d,(i=document.createElement("button")).innerText="Paste",i.onclick=function e(t){if(t.preventDefault(),o=document.getElementById(u).value,!(r=Number(document.getElementById(d).value)))return alert("Cannot proceed: delay number is invalid."),c();c(t),setTimeout($,500)},i.style.margin="8px",(l=document.createElement("button")).innerText="Cancel",l.onclick=c,e.append(t),e.append(n),e.append(a),e.append(document.createElement("br")),e.append(l),e.append(i),document.body.append(e)})();

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment