mirror of
https://github.com/gchq/CyberChef
synced 2025-01-09 02:58:46 +00:00
224 lines
8.3 KiB
JavaScript
Executable file
224 lines
8.3 KiB
JavaScript
Executable file
/**
|
|
* @author Matt C [matt@artemisbot.uk]
|
|
* @copyright Crown Copyright 2016
|
|
* @license Apache-2.0
|
|
*/
|
|
|
|
/**
|
|
* Waiter to handle keybindings to CyberChef functions (i.e. Bake, Step, Save, Load etc.)
|
|
*/
|
|
class BindingsWaiter {
|
|
|
|
/**
|
|
* BindingsWaiter constructor.
|
|
*
|
|
* @param {App} app - The main view object for CyberChef.
|
|
* @param {Manager} manager - The CyberChef event manager.
|
|
*/
|
|
constructor(app, manager) {
|
|
this.app = app;
|
|
this.manager = manager;
|
|
}
|
|
|
|
|
|
/**
|
|
* Handler for all keydown events
|
|
* Checks whether valid keyboard shortcut has been instated
|
|
*
|
|
* @fires Manager#statechange
|
|
* @param {event} e
|
|
*/
|
|
parseInput(e) {
|
|
const modKey = this.app.options.useMetaKey ? e.metaKey : e.altKey;
|
|
|
|
if (e.ctrlKey && modKey) {
|
|
let elem;
|
|
switch (e.code) {
|
|
case "KeyF": // Focus search
|
|
e.preventDefault();
|
|
document.getElementById("search").focus();
|
|
break;
|
|
case "KeyI": // Focus input
|
|
e.preventDefault();
|
|
document.getElementById("input-text").focus();
|
|
break;
|
|
case "KeyO": // Focus output
|
|
e.preventDefault();
|
|
document.getElementById("output-text").focus();
|
|
break;
|
|
case "Period": // Focus next operation
|
|
e.preventDefault();
|
|
try {
|
|
elem = document.activeElement.closest(".operation") || document.querySelector("#rec-list .operation");
|
|
if (elem.parentNode.lastChild === elem) {
|
|
// If operation is last in recipe, loop around to the top operation's first argument
|
|
elem.parentNode.firstChild.querySelectorAll(".arg")[0].focus();
|
|
} else {
|
|
// Focus first argument of next operation
|
|
elem.nextSibling.querySelectorAll(".arg")[0].focus();
|
|
}
|
|
} catch (e) {
|
|
// do nothing, just don't throw an error
|
|
}
|
|
break;
|
|
case "KeyB": // Set breakpoint
|
|
e.preventDefault();
|
|
try {
|
|
elem = document.activeElement.closest(".operation").querySelectorAll(".breakpoint")[0];
|
|
if (elem.getAttribute("break") === "false") {
|
|
elem.setAttribute("break", "true"); // add break point if not already enabled
|
|
elem.classList.add("breakpoint-selected");
|
|
} else {
|
|
elem.setAttribute("break", "false"); // remove break point if already enabled
|
|
elem.classList.remove("breakpoint-selected");
|
|
}
|
|
window.dispatchEvent(this.manager.statechange);
|
|
} catch (e) {
|
|
// do nothing, just don't throw an error
|
|
}
|
|
break;
|
|
case "KeyD": // Disable operation
|
|
e.preventDefault();
|
|
try {
|
|
elem = document.activeElement.closest(".operation").querySelectorAll(".disable-icon")[0];
|
|
if (elem.getAttribute("disabled") === "false") {
|
|
elem.setAttribute("disabled", "true"); // disable operation if enabled
|
|
elem.classList.add("disable-elem-selected");
|
|
elem.parentNode.parentNode.classList.add("disabled");
|
|
} else {
|
|
elem.setAttribute("disabled", "false"); // enable operation if disabled
|
|
elem.classList.remove("disable-elem-selected");
|
|
elem.parentNode.parentNode.classList.remove("disabled");
|
|
}
|
|
this.app.progress = 0;
|
|
window.dispatchEvent(this.manager.statechange);
|
|
} catch (e) {
|
|
// do nothing, just don't throw an error
|
|
}
|
|
break;
|
|
case "Space": // Bake
|
|
e.preventDefault();
|
|
this.app.bake();
|
|
break;
|
|
case "Quote": // Step through
|
|
e.preventDefault();
|
|
this.app.bake(true);
|
|
break;
|
|
case "KeyC": // Clear recipe
|
|
e.preventDefault();
|
|
this.manager.recipe.clearRecipe();
|
|
break;
|
|
case "KeyS": // Save output to file
|
|
e.preventDefault();
|
|
this.manager.output.saveClick();
|
|
break;
|
|
case "KeyL": // Load recipe
|
|
e.preventDefault();
|
|
this.manager.controls.loadClick();
|
|
break;
|
|
case "KeyM": // Switch input and output
|
|
e.preventDefault();
|
|
this.manager.output.switchClick();
|
|
break;
|
|
default:
|
|
if (e.code.match(/Digit[0-9]/g)) { // Select nth operation
|
|
e.preventDefault();
|
|
try {
|
|
// Select the first argument of the operation corresponding to the number pressed
|
|
document.querySelector(`li:nth-child(${e.code.substr(-1)}) .arg`).focus();
|
|
} catch (e) {
|
|
// do nothing, just don't throw an error
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Updates keybinding list when metaKey option is toggled
|
|
*/
|
|
updateKeybList() {
|
|
let modWinLin = "Alt";
|
|
let modMac = "Opt";
|
|
if (this.app.options.useMetaKey) {
|
|
modWinLin = "Win";
|
|
modMac = "Cmd";
|
|
}
|
|
document.getElementById("keybList").innerHTML = `
|
|
<tr>
|
|
<td><b>Command</b></td>
|
|
<td><b>Shortcut (Win/Linux)</b></td>
|
|
<td><b>Shortcut (Mac)</b></td>
|
|
</tr>
|
|
<tr>
|
|
<td>Place cursor in search field</td>
|
|
<td>Ctrl+${modWinLin}+f</td>
|
|
<td>Ctrl+${modMac}+f</td>
|
|
<tr>
|
|
<td>Place cursor in input box</td>
|
|
<td>Ctrl+${modWinLin}+i</td>
|
|
<td>Ctrl+${modMac}+i</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Place cursor in output box</td>
|
|
<td>Ctrl+${modWinLin}+o</td>
|
|
<td>Ctrl+${modMac}+o</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Place cursor in first argument field of the next operation in the recipe</td>
|
|
<td>Ctrl+${modWinLin}+.</td>
|
|
<td>Ctrl+${modMac}+.</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Place cursor in first argument field of the nth operation in the recipe</td>
|
|
<td>Ctrl+${modWinLin}+[1-9]</td>
|
|
<td>Ctrl+${modMac}+[1-9]</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Disable current operation</td>
|
|
<td>Ctrl+${modWinLin}+d</td>
|
|
<td>Ctrl+${modMac}+d</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Set/clear breakpoint</td>
|
|
<td>Ctrl+${modWinLin}+b</td>
|
|
<td>Ctrl+${modMac}+b</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Bake</td>
|
|
<td>Ctrl+${modWinLin}+Space</td>
|
|
<td>Ctrl+${modMac}+Space</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Step</td>
|
|
<td>Ctrl+${modWinLin}+'</td>
|
|
<td>Ctrl+${modMac}+'</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Clear recipe</td>
|
|
<td>Ctrl+${modWinLin}+c</td>
|
|
<td>Ctrl+${modMac}+c</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Save to file</td>
|
|
<td>Ctrl+${modWinLin}+s</td>
|
|
<td>Ctrl+${modMac}+s</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Load recipe</td>
|
|
<td>Ctrl+${modWinLin}+l</td>
|
|
<td>Ctrl+${modMac}+l</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Move output to input</td>
|
|
<td>Ctrl+${modWinLin}+m</td>
|
|
<td>Ctrl+${modMac}+m</td>
|
|
</tr>
|
|
`;
|
|
}
|
|
|
|
}
|
|
|
|
export default BindingsWaiter;
|