mirror of
https://github.com/gchq/CyberChef.git
synced 2025-04-21 07:16:17 -04:00
formatting
This commit is contained in:
parent
6fcf103760
commit
4c31c16eef
2 changed files with 75 additions and 94 deletions
|
@ -82,24 +82,24 @@ class StatusBarPanel {
|
|||
* @param {Event} e
|
||||
*/
|
||||
showDropUp(e) {
|
||||
if (e.type === "click" || e.keyCode === 13) {
|
||||
if (e.type === "click" || e.key === 'Enter'|| e.key === ' ') {
|
||||
const el = e.target
|
||||
.closest(".cm-status-bar-select")
|
||||
.querySelector(".cm-status-bar-select-content");
|
||||
const btn = e.target.closest(".cm-status-bar-select-btn");
|
||||
|
||||
if (btn.classList.contains("disabled")) return;
|
||||
if (btn.classList.contains("disabled")) return;
|
||||
|
||||
el.classList.add("show");
|
||||
el.classList.add("show");
|
||||
|
||||
// Focus the filter input if present
|
||||
const filter = el.querySelector(".cm-status-bar-filter-input");
|
||||
if (filter) filter.focus();
|
||||
// Focus the filter input if present
|
||||
const filter = el.querySelector(".cm-status-bar-filter-input");
|
||||
if (filter) filter.focus();
|
||||
|
||||
// Set up a listener to close the menu if the user clicks outside of it
|
||||
hideOnClickOutside(el, e);
|
||||
// Set up a listener to close the menu if the user presses key outside of it
|
||||
hideOnMoveFocus(el, e);
|
||||
// Set up a listener to close the menu if the user clicks outside of it
|
||||
hideOnClickOutside(el, e);
|
||||
// Set up a listener to close the menu if the user presses key outside of it
|
||||
hideOnMoveFocus(el, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -181,8 +181,7 @@ class StatusBarPanel {
|
|||
// CodeMirror always counts line breaks as one character.
|
||||
// We want to show an accurate reading of how many bytes there are.
|
||||
if (state.lineBreak.length !== 1) {
|
||||
docLength +=
|
||||
state.lineBreak.length * state.doc.lines - state.doc.lines - 1;
|
||||
docLength += (state.lineBreak.length * state.doc.lines) - state.doc.lines - 1;
|
||||
}
|
||||
length.textContent = docLength;
|
||||
lines.textContent = state.doc.lines;
|
||||
|
@ -237,6 +236,7 @@ class StatusBarPanel {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the current EOL separator in the status bar
|
||||
* @param {EditorState} state
|
||||
|
@ -344,7 +344,7 @@ class StatusBarPanel {
|
|||
*/
|
||||
constructLHS() {
|
||||
return `
|
||||
<span data-toggle="tooltip" tabindex="0" title="${this.label} length" data-help-title="${this.label} length" data-help="This number represents the number of characters in the ${this.label}.<br><br>The CRLF end of line separator is counted as two characters which impacts this value.">
|
||||
<span data-toggle="tooltip" tabindex="0" title="${this.label} length" data-help-title="${this.label} length" data-help="This number represents the number of characters in the ${this.label}.<br><br>The CRLF end of line separator is counted as two characters which impacts this value.">
|
||||
<i class="material-icons">abc</i>
|
||||
<span class="stats-length-value"></span>
|
||||
</span>
|
||||
|
@ -386,13 +386,13 @@ class StatusBarPanel {
|
|||
}
|
||||
|
||||
return `
|
||||
<span class="baking-time-info" style="display: none" data-toggle="tooltip" tabindex="0" data-html="true" title="Baking time" data-help-title="Baking time" data-help="The baking time is the total time between data being read from the input, processed, and then displayed in the output.<br><br>The 'Threading overhead' value accounts for the transfer of data between different processing threads, as well as some garbage collection. It is not included in the overall bake time displayed in the status bar as it is largely influenced by background operating system and browser activity which can fluctuate significantly.">
|
||||
<span class="baking-time-info" style="display: none" data-toggle="tooltip" tabindex="0" data-html="true" title="Baking time" data-help-title="Baking time" data-help="The baking time is the total time between data being read from the input, processed, and then displayed in the output.<br><br>The 'Threading overhead' value accounts for the transfer of data between different processing threads, as well as some garbage collection. It is not included in the overall bake time displayed in the status bar as it is largely influenced by background operating system and browser activity which can fluctuate significantly.">
|
||||
<i class="material-icons">schedule</i>
|
||||
<span class="baking-time-value"></span>ms
|
||||
</span>
|
||||
|
||||
<div class="cm-status-bar-select chr-enc-select" data-help-title="${this.label} character encoding" data-help="${chrEncHelpText}">
|
||||
<span class="cm-status-bar-select-btn" data-toggle="tooltip" tabindex="0" data-html="true" data-placement="left" title="${this.label} character encoding">
|
||||
<span class="cm-status-bar-select-btn" data-toggle="tooltip" tabindex="0" data-html="true" data-placement="left" title="${this.label} character encoding">
|
||||
<i class="material-icons">text_fields</i> <span class="chr-enc-value">Raw Bytes</span>
|
||||
</span>
|
||||
<div class="cm-status-bar-select-content">
|
||||
|
@ -427,6 +427,7 @@ class StatusBarPanel {
|
|||
</div>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const elementsWithListeners = {};
|
||||
|
@ -447,19 +448,14 @@ function hideOnClickOutside(element, instantiatingEvent) {
|
|||
// is not visible, or if this is the same click event that opened it.
|
||||
if (
|
||||
!element.contains(event.target) &&
|
||||
event.timeStamp !== instantiatingEvent.timeStamp
|
||||
) {
|
||||
event.timeStamp !== instantiatingEvent.timeStamp) {
|
||||
hideElement(element);
|
||||
}
|
||||
};
|
||||
|
||||
if (!Object.prototype.hasOwnProperty.call(elementsWithListeners, element)) {
|
||||
elementsWithListeners[element] = outsideClickListener;
|
||||
document.addEventListener(
|
||||
"click",
|
||||
elementsWithListeners[element],
|
||||
false
|
||||
);
|
||||
document.addEventListener("click", elementsWithListeners[element], false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -555,20 +551,13 @@ const arrowNav = (event) => {
|
|||
*/
|
||||
function hideElement(element) {
|
||||
element.classList.remove("show");
|
||||
document.removeEventListener(
|
||||
"click",
|
||||
elementsWithListeners[element],
|
||||
false
|
||||
);
|
||||
document.removeEventListener(
|
||||
"keydown",
|
||||
elementsWithKeyDownListeners[element],
|
||||
false
|
||||
);
|
||||
document.removeEventListener("click", elementsWithListeners[element], false);
|
||||
document.removeEventListener("keydown", elementsWithKeyDownListeners[element], false);
|
||||
delete elementsWithListeners[element];
|
||||
delete elementsWithKeyDownListeners[element];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A panel constructor factory building a panel that re-counts the stats every time the document changes.
|
||||
* @param {Object} opts
|
||||
|
@ -586,7 +575,7 @@ function makePanel(opts) {
|
|||
sbPanel.monitorHTMLOutput();
|
||||
|
||||
return {
|
||||
dom: sbPanel.dom,
|
||||
"dom": sbPanel.dom,
|
||||
update(update) {
|
||||
sbPanel.updateEOL(update.state);
|
||||
sbPanel.updateCharEnc();
|
||||
|
@ -599,7 +588,7 @@ function makePanel(opts) {
|
|||
if (update.docChanged) {
|
||||
sbPanel.updateStats(update.state);
|
||||
}
|
||||
},
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -6,10 +6,12 @@
|
|||
|
||||
import Utils from "../../core/Utils.mjs";
|
||||
|
||||
|
||||
/**
|
||||
* Waiter to handle events related to the CyberChef controls (i.e. Bake, Step, Save, Load etc.)
|
||||
*/
|
||||
class ControlsWaiter {
|
||||
|
||||
/**
|
||||
* ControlsWaiter constructor.
|
||||
*
|
||||
|
@ -21,6 +23,7 @@ class ControlsWaiter {
|
|||
this.manager = manager;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialise Bootstrap components
|
||||
*/
|
||||
|
@ -30,10 +33,11 @@ class ControlsWaiter {
|
|||
animation: false,
|
||||
container: "body",
|
||||
boundary: "viewport",
|
||||
trigger: "hover focus",
|
||||
trigger: "hover focus"
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks or unchecks the Auto Bake checkbox based on the given value.
|
||||
*
|
||||
|
@ -47,6 +51,7 @@ class ControlsWaiter {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handler to trigger baking.
|
||||
*/
|
||||
|
@ -59,6 +64,7 @@ class ControlsWaiter {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handler for the 'Step through' command. Executes the next step of the recipe.
|
||||
*/
|
||||
|
@ -66,6 +72,7 @@ class ControlsWaiter {
|
|||
this.app.step();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handler for changes made to the Auto Bake checkbox.
|
||||
*/
|
||||
|
@ -73,6 +80,7 @@ class ControlsWaiter {
|
|||
this.app.autoBake_ = document.getElementById("auto-bake").checked;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handler for the 'Clear recipe' command. Removes all operations from the recipe.
|
||||
*/
|
||||
|
@ -80,6 +88,7 @@ class ControlsWaiter {
|
|||
this.manager.recipe.clearRecipe();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Populates the save dialog box with a URL incorporating the recipe and input.
|
||||
*
|
||||
|
@ -88,23 +97,16 @@ class ControlsWaiter {
|
|||
initialiseSaveLink(recipeConfig) {
|
||||
recipeConfig = recipeConfig || this.app.getRecipeConfig();
|
||||
|
||||
const includeRecipe = document.getElementById(
|
||||
"save-link-recipe-checkbox"
|
||||
).checked;
|
||||
const includeInput = document.getElementById("save-link-input-checkbox")
|
||||
.checked;
|
||||
const includeRecipe = document.getElementById("save-link-recipe-checkbox").checked;
|
||||
const includeInput = document.getElementById("save-link-input-checkbox").checked;
|
||||
const saveLinkEl = document.getElementById("save-link");
|
||||
const saveLink = this.generateStateUrl(
|
||||
includeRecipe,
|
||||
includeInput,
|
||||
null,
|
||||
recipeConfig
|
||||
);
|
||||
const saveLink = this.generateStateUrl(includeRecipe, includeInput, null, recipeConfig);
|
||||
|
||||
saveLinkEl.innerHTML = Utils.escapeHtml(Utils.truncate(saveLink, 120));
|
||||
saveLinkEl.setAttribute("href", saveLink);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generates a URL containing the current recipe and input state.
|
||||
*
|
||||
|
@ -115,24 +117,15 @@ class ControlsWaiter {
|
|||
* @param {string} [baseURL] - The CyberChef URL, set to the current URL if not included
|
||||
* @returns {string}
|
||||
*/
|
||||
generateStateUrl(
|
||||
includeRecipe,
|
||||
includeInput,
|
||||
input,
|
||||
recipeConfig,
|
||||
baseURL
|
||||
) {
|
||||
generateStateUrl(includeRecipe, includeInput, input, recipeConfig, baseURL) {
|
||||
recipeConfig = recipeConfig || this.app.getRecipeConfig();
|
||||
|
||||
const link =
|
||||
baseURL ||
|
||||
window.location.protocol +
|
||||
"//" +
|
||||
const link = baseURL || window.location.protocol + "//" +
|
||||
window.location.host +
|
||||
window.location.pathname;
|
||||
const recipeStr = Utils.generatePrettyRecipe(recipeConfig);
|
||||
|
||||
includeRecipe = includeRecipe && recipeConfig.length > 0;
|
||||
includeRecipe = includeRecipe && (recipeConfig.length > 0);
|
||||
|
||||
// If we don't get passed an input, get it from the current URI
|
||||
if (input === null && includeInput) {
|
||||
|
@ -156,11 +149,11 @@ class ControlsWaiter {
|
|||
inputChrEnc !== 0 ? ["ienc", inputChrEnc] : undefined,
|
||||
outputChrEnc !== 0 ? ["oenc", outputChrEnc] : undefined,
|
||||
inputEOLSeq !== "\n" ? ["ieol", inputEOLSeq] : undefined,
|
||||
outputEOLSeq !== "\n" ? ["oeol", outputEOLSeq] : undefined,
|
||||
outputEOLSeq !== "\n" ? ["oeol", outputEOLSeq] : undefined
|
||||
];
|
||||
|
||||
const hash = params
|
||||
.filter((v) => v)
|
||||
.filter(v => v)
|
||||
.map(([key, value]) => `${key}=${Utils.encodeURIFragment(value)}`)
|
||||
.join("&");
|
||||
|
||||
|
@ -171,6 +164,7 @@ class ControlsWaiter {
|
|||
return link;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handler for changes made to the save dialog text area. Re-initialises the save link.
|
||||
*/
|
||||
|
@ -181,6 +175,7 @@ class ControlsWaiter {
|
|||
} catch (err) {}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handler for the 'Save' command. Pops up the save dialog box.
|
||||
*/
|
||||
|
@ -188,14 +183,8 @@ class ControlsWaiter {
|
|||
const recipeConfig = this.app.getRecipeConfig();
|
||||
const recipeStr = JSON.stringify(recipeConfig);
|
||||
|
||||
document.getElementById(
|
||||
"save-text-chef"
|
||||
).value = Utils.generatePrettyRecipe(recipeConfig, true);
|
||||
document.getElementById("save-text-clean").value = JSON.stringify(
|
||||
recipeConfig,
|
||||
null,
|
||||
2
|
||||
)
|
||||
document.getElementById("save-text-chef").value = Utils.generatePrettyRecipe(recipeConfig, true);
|
||||
document.getElementById("save-text-clean").value = JSON.stringify(recipeConfig, null, 2)
|
||||
.replace(/{\n\s+"/g, '{ "')
|
||||
.replace(/\[\n\s{3,}/g, "[")
|
||||
.replace(/\n\s{3,}]/g, "]")
|
||||
|
@ -207,6 +196,7 @@ class ControlsWaiter {
|
|||
$("#save-modal").modal();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handler for the save link recipe checkbox change event.
|
||||
*/
|
||||
|
@ -214,6 +204,7 @@ class ControlsWaiter {
|
|||
this.initialiseSaveLink();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handler for the save link input checkbox change event.
|
||||
*/
|
||||
|
@ -221,6 +212,7 @@ class ControlsWaiter {
|
|||
this.initialiseSaveLink();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handler for the 'Load' command. Pops up the load dialog box.
|
||||
*/
|
||||
|
@ -229,6 +221,7 @@ class ControlsWaiter {
|
|||
$("#load-modal").modal();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Saves the recipe specified in the save textarea to local storage.
|
||||
*/
|
||||
|
@ -241,25 +234,22 @@ class ControlsWaiter {
|
|||
return false;
|
||||
}
|
||||
|
||||
const recipeName = Utils.escapeHtml(
|
||||
document.getElementById("save-name").value
|
||||
);
|
||||
const recipeStr = document.querySelector(
|
||||
"#save-texts .tab-pane.active textarea"
|
||||
).value;
|
||||
const recipeName = Utils.escapeHtml(document.getElementById("save-name").value);
|
||||
const recipeStr = document.querySelector("#save-texts .tab-pane.active textarea").value;
|
||||
|
||||
if (!recipeName) {
|
||||
this.app.alert("Please enter a recipe name", 3000);
|
||||
return;
|
||||
}
|
||||
|
||||
const savedRecipes = localStorage.savedRecipes ? JSON.parse(localStorage.savedRecipes) : [];
|
||||
const savedRecipes = localStorage.savedRecipes ?
|
||||
JSON.parse(localStorage.savedRecipes) : [];
|
||||
let recipeId = localStorage.recipeId || 0;
|
||||
|
||||
savedRecipes.push({
|
||||
id: ++recipeId,
|
||||
name: recipeName,
|
||||
recipe: recipeStr,
|
||||
recipe: recipeStr
|
||||
});
|
||||
|
||||
localStorage.savedRecipes = JSON.stringify(savedRecipes);
|
||||
|
@ -268,6 +258,7 @@ class ControlsWaiter {
|
|||
this.app.alert(`Recipe saved as "${recipeName}".`, 3000);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Populates the list of saved recipes in the load dialog box from local storage.
|
||||
*/
|
||||
|
@ -283,15 +274,14 @@ class ControlsWaiter {
|
|||
}
|
||||
|
||||
// Add recipes to select
|
||||
const savedRecipes = localStorage.savedRecipes ? JSON.parse(localStorage.savedRecipes) : [];
|
||||
const savedRecipes = localStorage.savedRecipes ?
|
||||
JSON.parse(localStorage.savedRecipes) : [];
|
||||
|
||||
for (i = 0; i < savedRecipes.length; i++) {
|
||||
const opt = document.createElement("option");
|
||||
opt.value = savedRecipes[i].id;
|
||||
// Unescape then re-escape in case localStorage has been corrupted
|
||||
opt.innerHTML = Utils.escapeHtml(
|
||||
Utils.unescapeHtml(savedRecipes[i].name)
|
||||
);
|
||||
opt.innerHTML = Utils.escapeHtml(Utils.unescapeHtml(savedRecipes[i].name));
|
||||
|
||||
loadNameEl.appendChild(opt);
|
||||
}
|
||||
|
@ -303,6 +293,7 @@ class ControlsWaiter {
|
|||
loadText.dispatchEvent(evt);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes the currently selected recipe from local storage.
|
||||
*/
|
||||
|
@ -310,14 +301,16 @@ class ControlsWaiter {
|
|||
if (!this.app.isLocalStorageAvailable()) return false;
|
||||
|
||||
const id = parseInt(document.getElementById("load-name").value, 10);
|
||||
const rawSavedRecipes = localStorage.savedRecipes ? JSON.parse(localStorage.savedRecipes) : [];
|
||||
const rawSavedRecipes = localStorage.savedRecipes ?
|
||||
JSON.parse(localStorage.savedRecipes) : [];
|
||||
|
||||
const savedRecipes = rawSavedRecipes.filter((r) => r.id !== id);
|
||||
const savedRecipes = rawSavedRecipes.filter(r => r.id !== id);
|
||||
|
||||
localStorage.savedRecipes = JSON.stringify(savedRecipes);
|
||||
this.populateLoadRecipesList();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Displays the selected recipe in the load text box.
|
||||
*/
|
||||
|
@ -325,22 +318,22 @@ class ControlsWaiter {
|
|||
if (!this.app.isLocalStorageAvailable()) return false;
|
||||
|
||||
const el = e.target;
|
||||
const savedRecipes = localStorage.savedRecipes ? JSON.parse(localStorage.savedRecipes) : [];
|
||||
const savedRecipes = localStorage.savedRecipes ?
|
||||
JSON.parse(localStorage.savedRecipes) : [];
|
||||
const id = parseInt(el.value, 10);
|
||||
|
||||
const recipe = savedRecipes.find((r) => r.id === id);
|
||||
const recipe = savedRecipes.find(r => r.id === id);
|
||||
|
||||
document.getElementById("load-text").value = recipe.recipe;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Loads the selected recipe and populates the Recipe with its operations.
|
||||
*/
|
||||
loadButtonClick() {
|
||||
try {
|
||||
const recipeConfig = Utils.parseRecipeConfig(
|
||||
document.getElementById("load-text").value
|
||||
);
|
||||
const recipeConfig = Utils.parseRecipeConfig(document.getElementById("load-text").value);
|
||||
this.app.setRecipeConfig(recipeConfig);
|
||||
this.app.autoBake();
|
||||
|
||||
|
@ -350,6 +343,7 @@ class ControlsWaiter {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Populates the bug report information box with useful technical info.
|
||||
*
|
||||
|
@ -359,13 +353,7 @@ class ControlsWaiter {
|
|||
e.preventDefault();
|
||||
|
||||
const reportBugInfo = document.getElementById("report-bug-info");
|
||||
const saveLink = this.generateStateUrl(
|
||||
true,
|
||||
true,
|
||||
null,
|
||||
null,
|
||||
"https://gchq.github.io/CyberChef/"
|
||||
);
|
||||
const saveLink = this.generateStateUrl(true, true, null, null, "https://gchq.github.io/CyberChef/");
|
||||
|
||||
if (reportBugInfo) {
|
||||
reportBugInfo.innerHTML = `* Version: ${PKG_VERSION}
|
||||
|
@ -378,6 +366,7 @@ ${navigator.userAgent}
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Shows the stale indicator to show that the input or recipe has changed
|
||||
* since the last bake.
|
||||
|
@ -387,6 +376,7 @@ ${navigator.userAgent}
|
|||
staleIndicator.classList.remove("hidden");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Hides the stale indicator to show that the input or recipe has not changed
|
||||
* since the last bake.
|
||||
|
@ -396,6 +386,7 @@ ${navigator.userAgent}
|
|||
staleIndicator.classList.add("hidden");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Switches the Bake button between 'Bake', 'Cancel' and 'Loading' functions.
|
||||
*
|
||||
|
@ -438,6 +429,7 @@ ${navigator.userAgent}
|
|||
|
||||
recList.style.bottom = controls.clientHeight + "px";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default ControlsWaiter;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue