mirror of
https://github.com/gchq/CyberChef.git
synced 2025-05-10 08:15:00 -04:00
Initial async work
Operations can now: 1) return their progress directly. 2) throw an error. 3) (ADDED) return a promise: + that resolves to their progress. + that rejects an error message (like throwing but asynchronous). For an example see the new operation "Wait" (Flow Control) Added a flow control operation "Wait", which waits for the number of milliseconds passed in as its argument. It is a fairly useless operation but it does demonstrate how asynchronous operations now work. A recipe like: ``` Fork Wait (1000ms) ``` will only wait for 1000ms (each wait runs at the same time as each other). I have not looked into performance implications yet, also this code is probably more complicated than it needs to be (would love help on this).
This commit is contained in:
parent
11e972ff26
commit
343d350af8
8 changed files with 346 additions and 108 deletions
|
@ -28,6 +28,9 @@ var HTMLApp = function(categories, operations, defaultFavourites, defaultOptions
|
|||
this.progress = 0;
|
||||
this.ingId = 0;
|
||||
|
||||
this.baking = false;
|
||||
this.rebake = false;
|
||||
|
||||
window.chef = this.chef;
|
||||
};
|
||||
|
||||
|
@ -61,6 +64,36 @@ HTMLApp.prototype.handleError = function(err) {
|
|||
};
|
||||
|
||||
|
||||
/**
|
||||
* Updates the UI to show if baking is in process or not.
|
||||
*
|
||||
* @param {bakingStatus}
|
||||
*/
|
||||
HTMLApp.prototype.setBakingStatus = function(bakingStatus) {
|
||||
var inputLoadingIcon = document.querySelector("#input .title .loading-icon");
|
||||
var outputLoadingIcon = document.querySelector("#output .title .loading-icon");
|
||||
|
||||
var inputElement = document.querySelector("#input-text");
|
||||
var outputElement = document.querySelector("#output-text");
|
||||
|
||||
if (bakingStatus) {
|
||||
inputLoadingIcon.style.display = "inline-block";
|
||||
outputLoadingIcon.style.display = "inline-block";
|
||||
inputElement.classList.add("disabled");
|
||||
outputElement.classList.add("disabled");
|
||||
inputElement.disabled = true;
|
||||
outputElement.disabled = true;
|
||||
} else {
|
||||
inputLoadingIcon.style.display = "none";
|
||||
outputLoadingIcon.style.display = "none";
|
||||
inputElement.classList.remove("disabled");
|
||||
outputElement.classList.remove("disabled");
|
||||
inputElement.disabled = false;
|
||||
outputElement.disabled = false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Calls the Chef to bake the current input using the current recipe.
|
||||
*
|
||||
|
@ -68,37 +101,70 @@ HTMLApp.prototype.handleError = function(err) {
|
|||
* whole recipe.
|
||||
*/
|
||||
HTMLApp.prototype.bake = function(step) {
|
||||
var response;
|
||||
var app = this;
|
||||
|
||||
if (app.baking) {
|
||||
if (!app.rebake) {
|
||||
// We do not want to keep autobaking
|
||||
// Say that we will rebake and then try again later
|
||||
app.rebake = true;
|
||||
setTimeout(function() {
|
||||
app.bake(step);
|
||||
}, 500);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
app.rebake = false;
|
||||
app.baking = true;
|
||||
app.setBakingStatus(true);
|
||||
|
||||
try {
|
||||
response = this.chef.bake(
|
||||
this.getInput(), // The user's input
|
||||
this.getRecipeConfig(), // The configuration of the recipe
|
||||
this.options, // Options set by the user
|
||||
this.progress, // The current position in the recipe
|
||||
app.chef.bake(
|
||||
app.getInput(), // The user's input
|
||||
app.getRecipeConfig(), // The configuration of the recipe
|
||||
app.options, // Options set by the user
|
||||
app.progress, // The current position in the recipe
|
||||
step // Whether or not to take one step or execute the whole recipe
|
||||
);
|
||||
)
|
||||
.then(function(response) {
|
||||
app.baking = false;
|
||||
app.setBakingStatus(false);
|
||||
|
||||
if (!response) {
|
||||
return;
|
||||
}
|
||||
if (response.error) {
|
||||
app.handleError(response.error);
|
||||
}
|
||||
|
||||
app.options = response.options;
|
||||
|
||||
if (response.type === "html") {
|
||||
app.dishStr = Utils.stripHtmlTags(response.result, true);
|
||||
} else {
|
||||
app.dishStr = response.result;
|
||||
}
|
||||
|
||||
app.progress = response.progress;
|
||||
app.manager.recipe.updateBreakpointIndicator(response.progress);
|
||||
app.manager.output.set(response.result, response.type, response.duration);
|
||||
|
||||
// If baking took too long, disable auto-bake
|
||||
if (response.duration > app.options.autoBakeThreshold && app.autoBake_) {
|
||||
app.manager.controls.setAutoBake(false);
|
||||
app.alert("Baking took longer than " + app.options.autoBakeThreshold +
|
||||
"ms, Auto Bake has been disabled.", "warning", 5000);
|
||||
}
|
||||
})
|
||||
.catch(function(err) {
|
||||
console.error("Chef's promise was rejected, should never occur");
|
||||
});
|
||||
} catch (err) {
|
||||
this.handleError(err);
|
||||
}
|
||||
|
||||
if (!response) return;
|
||||
|
||||
if (response.error) {
|
||||
this.handleError(response.error);
|
||||
}
|
||||
|
||||
this.options = response.options;
|
||||
this.dishStr = response.type === "html" ? Utils.stripHtmlTags(response.result, true) : response.result;
|
||||
this.progress = response.progress;
|
||||
this.manager.recipe.updateBreakpointIndicator(response.progress);
|
||||
this.manager.output.set(response.result, response.type, response.duration);
|
||||
|
||||
// If baking took too long, disable auto-bake
|
||||
if (response.duration > this.options.autoBakeThreshold && this.autoBake_) {
|
||||
this.manager.controls.setAutoBake(false);
|
||||
this.alert("Baking took longer than " + this.options.autoBakeThreshold +
|
||||
"ms, Auto Bake has been disabled.", "warning", 5000);
|
||||
app.baking = false;
|
||||
app.setBakingStatus(false);
|
||||
app.handleError(err);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue