Add swap inputs feature

This commit is contained in:
Patrick Lekaj 2019-08-25 22:10:25 +02:00
parent d3e3e6e6fc
commit 88c7843924
12 changed files with 78 additions and 16 deletions

View file

@ -24,6 +24,7 @@ class Operation {
this._disabled = false; this._disabled = false;
this._flowControl = false; this._flowControl = false;
this._manualBake = false; this._manualBake = false;
this._inputSwapable = false;
this._ingList = []; this._ingList = [];
// Public fields // Public fields
@ -316,6 +317,25 @@ class Operation {
this._manualBake = !!value; this._manualBake = !!value;
} }
/**
* Returns true if this Operation has swapable input values.
*
* @returns {boolean}
*/
get inputSwapable() {
return this._inputSwapable;
}
/**
* Set whether this Operation shoud show swap input icon.
*
* @param {boolean} value
*/
set inputSwapable(value) {
this._inputSwapable = !!value;
}
} }
export default Operation; export default Operation;

View file

@ -35,14 +35,15 @@ for (const opObj in Ops) {
const op = new Ops[opObj](); const op = new Ops[opObj]();
operationConfig[op.name] = { operationConfig[op.name] = {
module: op.module, module: op.module,
description: op.description, description: op.description,
infoURL: op.infoURL, infoURL: op.infoURL,
inputType: op.inputType, inputType: op.inputType,
outputType: op.presentType, outputType: op.presentType,
flowControl: op.flowControl, flowControl: op.flowControl,
manualBake: op.manualBake, inputSwapable: op.inputSwapable,
args: op.args manualBake: op.manualBake,
args: op.args
}; };
if ("patterns" in op) { if ("patterns" in op) {

View file

@ -77,6 +77,14 @@ If your operation does not rely on a library, just leave this blank and it will
required: true, required: true,
message: `The output type should be one of: ${ioTypes.join(", ")}.` message: `The output type should be one of: ${ioTypes.join(", ")}.`
}, },
inputSwapable: {
description: "Input swappable option shows an icon that can swap input values of two ingredients.",
example: "true/false",
prompt: "Show input swaping",
type: "boolean",
default: "false",
message: "Enter true or false to specify if input spawing should be shown."
},
highlight: { highlight: {
description: "If your operation does not change the length of the input in any way, we can enable highlighting. If it does change the length in a predictable way, we may still be able to enable highlighting and calculate the correct offsets. If this is not possible, we will disable highlighting for this operation.", description: "If your operation does not change the length of the input in any way, we can enable highlighting. If it does change the length in a predictable way, we may still be able to enable highlighting and calculate the correct offsets. If this is not possible, we will disable highlighting for this operation.",
example: "true/false", example: "true/false",
@ -150,6 +158,7 @@ class ${moduleName} extends Operation {
this.infoURL = "${result.infoURL}"; this.infoURL = "${result.infoURL}";
this.inputType = "${result.inputType}"; this.inputType = "${result.inputType}";
this.outputType = "${result.outputType}"; this.outputType = "${result.outputType}";
this.inputSwapable = "${result.inputSwapable}";
this.args = [ this.args = [
/* Example arguments. See the project wiki for full details. /* Example arguments. See the project wiki for full details.
{ {

View file

@ -23,6 +23,7 @@ class ConvertArea extends Operation {
this.infoURL = "https://wikipedia.org/wiki/Orders_of_magnitude_(area)"; this.infoURL = "https://wikipedia.org/wiki/Orders_of_magnitude_(area)";
this.inputType = "BigNumber"; this.inputType = "BigNumber";
this.outputType = "BigNumber"; this.outputType = "BigNumber";
this.inputSwapable = true;
this.args = [ this.args = [
{ {
"name": "Input units", "name": "Input units",

View file

@ -23,6 +23,7 @@ class ConvertDataUnits extends Operation {
this.infoURL = "https://wikipedia.org/wiki/Orders_of_magnitude_(data)"; this.infoURL = "https://wikipedia.org/wiki/Orders_of_magnitude_(data)";
this.inputType = "BigNumber"; this.inputType = "BigNumber";
this.outputType = "BigNumber"; this.outputType = "BigNumber";
this.inputSwapable = true;
this.args = [ this.args = [
{ {
"name": "Input units", "name": "Input units",

View file

@ -23,6 +23,7 @@ class ConvertDistance extends Operation {
this.infoURL = "https://wikipedia.org/wiki/Orders_of_magnitude_(length)"; this.infoURL = "https://wikipedia.org/wiki/Orders_of_magnitude_(length)";
this.inputType = "BigNumber"; this.inputType = "BigNumber";
this.outputType = "BigNumber"; this.outputType = "BigNumber";
this.inputSwapable = true;
this.args = [ this.args = [
{ {
"name": "Input units", "name": "Input units",

View file

@ -23,6 +23,7 @@ class ConvertMass extends Operation {
this.infoURL = "https://wikipedia.org/wiki/Orders_of_magnitude_(mass)"; this.infoURL = "https://wikipedia.org/wiki/Orders_of_magnitude_(mass)";
this.inputType = "BigNumber"; this.inputType = "BigNumber";
this.outputType = "BigNumber"; this.outputType = "BigNumber";
this.inputSwapable = true;
this.args = [ this.args = [
{ {
"name": "Input units", "name": "Input units",

View file

@ -23,6 +23,7 @@ class ConvertSpeed extends Operation {
this.infoURL = "https://wikipedia.org/wiki/Orders_of_magnitude_(speed)"; this.infoURL = "https://wikipedia.org/wiki/Orders_of_magnitude_(speed)";
this.inputType = "BigNumber"; this.inputType = "BigNumber";
this.outputType = "BigNumber"; this.outputType = "BigNumber";
this.inputSwapable = true;
this.args = [ this.args = [
{ {
"name": "Input units", "name": "Input units",

View file

@ -21,15 +21,16 @@ class HTMLOperation {
* @param {Manager} manager - The CyberChef event manager. * @param {Manager} manager - The CyberChef event manager.
*/ */
constructor(name, config, app, manager) { constructor(name, config, app, manager) {
this.app = app; this.app = app;
this.manager = manager; this.manager = manager;
this.name = name; this.name = name;
this.description = config.description; this.description = config.description;
this.infoURL = config.infoURL; this.infoURL = config.infoURL;
this.manualBake = config.manualBake || false; this.manualBake = config.manualBake || false;
this.config = config; this.inputSwappable = config.inputSwappable || false;
this.ingList = []; this.config = config;
this.ingList = [];
for (let i = 0; i < config.args.length; i++) { for (let i = 0; i < config.args.length; i++) {
const ing = new HTMLIngredient(config.args[i], this.app, this.manager); const ing = new HTMLIngredient(config.args[i], this.app, this.manager);
@ -77,6 +78,9 @@ class HTMLOperation {
for (let i = 0; i < this.ingList.length; i++) { for (let i = 0; i < this.ingList.length; i++) {
html += this.ingList[i].toHtml(); html += this.ingList[i].toHtml();
if (this.inputSwappable && i === 0) {
html += "<div class='inline'><i class='material-icons swap-icon' title='Swap input'>swap_horiz</i></div>";
}
} }
html += `</div> html += `</div>

View file

@ -137,6 +137,7 @@ class Manager {
this.addDynamicListener(".arg[type=checkbox], .arg[type=radio], select.arg", "change", this.recipe.ingChange, this.recipe); this.addDynamicListener(".arg[type=checkbox], .arg[type=radio], select.arg", "change", this.recipe.ingChange, this.recipe);
this.addDynamicListener(".disable-icon", "click", this.recipe.disableClick, this.recipe); this.addDynamicListener(".disable-icon", "click", this.recipe.disableClick, this.recipe);
this.addDynamicListener(".breakpoint", "click", this.recipe.breakpointClick, this.recipe); this.addDynamicListener(".breakpoint", "click", this.recipe.breakpointClick, this.recipe);
this.addDynamicListener(".swap-icon", "click", this.recipe.swapInputClick, this.recipe);
this.addDynamicListener("#rec-list li.operation", "dblclick", this.recipe.operationDblclick, this.recipe); this.addDynamicListener("#rec-list li.operation", "dblclick", this.recipe.operationDblclick, this.recipe);
this.addDynamicListener("#rec-list li.operation > div", "dblclick", this.recipe.operationChildDblclick, this.recipe); this.addDynamicListener("#rec-list li.operation > div", "dblclick", this.recipe.operationChildDblclick, this.recipe);
this.addDynamicListener("#rec-list .dropdown-menu.toggle-dropdown a", "click", this.recipe.dropdownToggleClick, this.recipe); this.addDynamicListener("#rec-list .dropdown-menu.toggle-dropdown a", "click", this.recipe.dropdownToggleClick, this.recipe);

View file

@ -240,6 +240,11 @@ div.toggle-string {
cursor: pointer; cursor: pointer;
} }
.swap-icon {
margin-top: 1.75rem;
cursor: pointer;
}
.disable-icon { .disable-icon {
color: var(--disable-icon-colour); color: var(--disable-icon-colour);
} }

View file

@ -261,6 +261,23 @@ class RecipeWaiter {
window.dispatchEvent(this.manager.statechange); window.dispatchEvent(this.manager.statechange);
} }
/**
* Handler for swap input click event.
* Swaps values of two inputs.
*
* @fires Manager#statechange
* @param {event} e
*/
swapInputClick(e) {
const si = e.target;
const ings = si.parentNode.parentNode.querySelectorAll(".arg");
if (ings.length === 2) {
const left = ings[0], right = ings[1];
[left.value, right.value] = [right.value, left.value];
this.ingChange();
}
}
/** /**
* Handler for operation doubleclick events. * Handler for operation doubleclick events.