Last active
May 5, 2024 12:41
-
-
Save folknor/35d406aa846a29a1e2bc0e0e5d0da4e0 to your computer and use it in GitHub Desktop.
Violentmonkey Script for KLE
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name KLE Floating Window | |
// @namespace folknor.KLE | |
// @version 1.2.2 | |
// @author folk | |
// @description Quality of life fixes for KLE. | |
// @grant none | |
// @match *://www.keyboard-layout-editor.com/* | |
// @run-at document-idle | |
// @inject-into page | |
// @downloadURL https://gist.githubusercontent.com/folknor/35d406aa846a29a1e2bc0e0e5d0da4e0/raw/vm-kle.js | |
// @updateURL https://gist.githubusercontent.com/folknor/35d406aa846a29a1e2bc0e0e5d0da4e0/raw/vm-kle.js | |
// ==/UserScript== | |
const floatingWindow = document.createElement('div'); | |
floatingWindow.style.position = 'fixed'; | |
floatingWindow.style.top = '50px'; | |
floatingWindow.style.left = '50px'; | |
floatingWindow.style.width = '650px'; | |
floatingWindow.style.height = '580px'; | |
floatingWindow.style.background = 'white'; | |
floatingWindow.style.border = '4px solid black'; | |
floatingWindow.style.zIndex = '1000'; | |
floatingWindow.style.overflow = 'hidden'; | |
const dragHandle = document.createElement('div'); | |
dragHandle.style.height = '12px'; | |
dragHandle.style.background = 'gray'; | |
dragHandle.style.cursor = 'move'; | |
dragHandle.style.zIndex = '1600'; | |
floatingWindow.appendChild(dragHandle); | |
const resizeHandle = document.createElement('div'); | |
resizeHandle.style.width = '0'; | |
resizeHandle.style.height = '0'; | |
resizeHandle.style.borderLeft = '8px solid transparent'; | |
resizeHandle.style.borderRight = '8px solid transparent'; | |
resizeHandle.style.borderBottom = '8px solid black'; | |
resizeHandle.style.cursor = 'nwse-resize'; | |
resizeHandle.style.position = 'absolute'; | |
resizeHandle.style.bottom = '-2px'; | |
resizeHandle.style.right = '-6px'; | |
resizeHandle.style.transform = 'rotate(135deg)'; | |
resizeHandle.style.zIndex = '1600'; | |
floatingWindow.appendChild(resizeHandle); | |
// Move the stuff | |
const element1 = document.querySelector('html.ng-scope body.ng-scope div#wrap div#body_all div.body ul.nav.nav-tabs'); | |
const element2 = document.querySelector('html.ng-scope body.ng-scope div#wrap div#body_all div.body div#tab-content.col-md-12.col-lg-12.row'); | |
const element3 = document.querySelector('html.ng-scope body.ng-scope div#wrap div#body_all div.body div.row'); | |
floatingWindow.appendChild(element1); | |
floatingWindow.appendChild(element2); | |
floatingWindow.appendChild(element3); | |
setTimeout(function() { | |
// Remove some CSS classes from the key properties form to make it jump around less | |
const keyProps = document.querySelector('div#properties form'); | |
keyProps.classList.remove("col-sm-8"); | |
keyProps.classList.remove("col-md-5"); | |
keyProps.classList.remove("col-lg-5"); | |
keyProps.classList.add("col"); | |
// Change to nav pills | |
let navEls = document.querySelectorAll("html.ng-scope body.ng-scope div ul.nav.nav-tabs"); | |
navEls.forEach(el => { | |
el.classList.remove("nav-tabs"); | |
el.classList.add("nav-pills"); | |
el.classList.add("nav-justified"); | |
el.querySelectorAll("a").forEach(anchor => { | |
anchor.style.paddingTop = "6px"; | |
anchor.style.paddingBottom = "6px"; | |
anchor.style.paddingLeft = "8px"; | |
anchor.style.paddingRight = "8px"; | |
}) | |
}); | |
let tabContent = document.getElementById("tab-content"); | |
tabContent.style.borderBottom = "none"; | |
tabContent.style.borderRight = "none"; | |
tabContent.style.borderLeft = "none"; | |
tabContent.style.paddingBottom = "0px"; | |
}, 500); | |
document.body.appendChild(floatingWindow); | |
function isElementVisible(elm) { | |
const rect = elm.getBoundingClientRect(); | |
return rect.top >= 0 && rect.left >= 0 && | |
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && | |
rect.right <= (window.innerWidth || document.documentElement.clientWidth); | |
} | |
let isDragging = false; | |
let offsetX, offsetY; | |
// Make sure the window is moved back if moved outside the bounds gg | |
setInterval(() => { | |
const dragHandleHidden = !isElementVisible(dragHandle); | |
if (dragHandleHidden) { | |
const rect = dragHandle.getBoundingClientRect(); | |
const windowHeight = window.innerHeight || document.documentElement.clientHeight; | |
const windowWidth = window.innerWidth || document.documentElement.clientWidth; | |
if (rect.bottom < 0 || rect.top > windowHeight || rect.right < 0 || rect.left > windowWidth) { | |
floatingWindow.style.left = `${Math.max(0, Math.min(windowWidth - floatingWindow.offsetWidth, parseFloat(floatingWindow.style.left)))}px`; | |
floatingWindow.style.top = `${Math.max(0, Math.min(windowHeight - floatingWindow.offsetHeight, parseFloat(floatingWindow.style.top)))}px`; | |
} | |
} | |
}, 1000); | |
dragHandle.addEventListener('mousedown', (e) => { | |
isDragging = true; | |
offsetX = e.clientX - floatingWindow.getBoundingClientRect().left; | |
offsetY = e.clientY - floatingWindow.getBoundingClientRect().top; | |
}); | |
document.addEventListener('mousemove', (e) => { | |
if (isDragging) { | |
floatingWindow.style.left = `${e.clientX - offsetX}px`; | |
floatingWindow.style.top = `${e.clientY - offsetY}px`; | |
} | |
}); | |
document.addEventListener('mouseup', () => { | |
isDragging = false; | |
}); | |
let isResizing = false; | |
resizeHandle.addEventListener('mousedown', (e) => { | |
isResizing = true; | |
const rect = floatingWindow.getBoundingClientRect(); | |
offsetX = e.clientX - rect.right; | |
offsetY = e.clientY - rect.bottom; | |
}); | |
document.addEventListener('mousemove', (e) => { | |
if (isResizing) { | |
floatingWindow.style.width = `${e.clientX - floatingWindow.getBoundingClientRect().left + offsetX}px`; | |
floatingWindow.style.height = `${e.clientY - floatingWindow.getBoundingClientRect().top + offsetY}px`; | |
} | |
}); | |
document.addEventListener('mouseup', () => { | |
isResizing = false; | |
}); | |
document.addEventListener('keyup', function(event) { | |
if (event.key === 'Enter') { | |
var num = -1; | |
try { | |
num = parseInt(document.querySelector('.key.selected .keylabels').firstElementChild.className.match(/\d+/)[0]); | |
} catch (err) { | |
// noop | |
} | |
if (num == -1 || typeof num === 'undefined') { | |
num = 0; | |
} | |
const inputBox = document.getElementById(`labeleditor${num}`); | |
if (inputBox) { | |
event.stopPropagation(); | |
event.stopImmediatePropagation(); | |
// If we have focus already, then select the next or previous key | |
if (document.activeElement && document.activeElement == inputBox) { | |
var ev; | |
if (event.shiftKey) { | |
ev = new KeyboardEvent('keydown', { | |
key: 'j', | |
keyCode: 74, | |
bubbles: true | |
}); | |
} else { | |
ev = new KeyboardEvent('keydown', { | |
key: 'k', | |
keyCode: 75, | |
bubbles: true | |
}); | |
} | |
document.querySelector('.key.selected').dispatchEvent(ev); | |
} else { | |
inputBox.setSelectionRange(0, inputBox.value.length) | |
inputBox.focus(); | |
} | |
} | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
v1.2.2 20240505 14:30 CET
v1.2 20240427 19:36 CET
v1.1 20240427 19:26 CET