// ==UserScript==
// @name Proxmox swap embedded console
// @version 1.0
// @description Swap noVNC to xterm.js in Proxmox embedded console
// @match *://*/
// @include /^https:\/\/.*:8006\/#v.*:=node%2F.*:.*:=consolejs:$/
// @grant none
// ==/UserScript==
(function() {
'use strict';
function modifyConsoleSource(div) {
const iframe = div.querySelector('iframe');
if (iframe && iframe.src) {
const urlParams = new URLSearchParams(iframe.src.split('?')[1]);
const vmid = urlParams.get('vmid');
const node = urlParams.get('node');
if (vmid && node) {
const newSrc = `/?console=kvm&xtermjs=1&vmid=${vmid}&node=${node}&cmd=`;
const currentSrc = new URL(iframe.src, window.location.origin).toString();
const normalizedNewSrc = new URL(newSrc, window.location.origin).toString();
if (currentSrc !== normalizedNewSrc) {
iframe.src = newSrc;
console.log('Modified iframe src:', newSrc);
} else {
setTimeout(() => {}, 1000);
}
} else {
console.err('Could not extract vmid or node from iframe src');
}
} else {
setTimeout(() => {
console.warn('Iframe not found within div, sleeping 3 seconds');
}, 3000);
}
}
function checkIfPageHasConsole() {
const pve_div = document.querySelector('div[id^="PVE-qemu-Config-"]');
const lxc_div = document.querySelector('div[id^="pveLXCConfig-"]');
const novnc_div = document.querySelector('div[id^="pveNoVncConsole-"]');
if (novnc_div && pve_div &&! lxc_div) {
modifyConsoleSource(novnc_div)
}
}
const observer = new MutationObserver(checkIfPageHasConsole);
observer.observe(document.body, { childList: true, subtree: true });
})();