Added populateMultiOption ingredient type

This commit is contained in:
n1474335 2019-02-08 00:59:56 +00:00 committed by s2224834
parent 87e956fe7d
commit 53226c1050
5 changed files with 92 additions and 76 deletions

1
.gitignore vendored
View file

@ -7,6 +7,7 @@ docs/*
!docs/*.ico !docs/*.ico
.vscode .vscode
.*.swp .*.swp
.DS_Store
src/core/config/modules/* src/core/config/modules/*
src/core/config/OperationConfig.json src/core/config/OperationConfig.json
src/core/operations/index.mjs src/core/operations/index.mjs

View file

@ -60,95 +60,57 @@ class MultipleBombe extends Operation {
this.args = [ this.args = [
{ {
"name": "Standard Enigmas", "name": "Standard Enigmas",
"type": "populateOption", "type": "populateMultiOption",
"value": [ "value": [
{ {
name: "German Service Enigma (First - 3 rotor)", name: "German Service Enigma (First - 3 rotor)",
value: rotorsFormat(ROTORS, 0, 5) value: [
rotorsFormat(ROTORS, 0, 5),
"",
rotorsFormat(REFLECTORS, 0, 1)
]
}, },
{ {
name: "German Service Enigma (Second - 3 rotor)", name: "German Service Enigma (Second - 3 rotor)",
value: rotorsFormat(ROTORS, 0, 8) value: [
rotorsFormat(ROTORS, 0, 8),
"",
rotorsFormat(REFLECTORS, 0, 2)
]
}, },
{ {
name: "German Service Enigma (Third - 4 rotor)", name: "German Service Enigma (Third - 4 rotor)",
value: rotorsFormat(ROTORS, 0, 8) value: [
rotorsFormat(ROTORS, 0, 8),
rotorsFormat(ROTORS_FOURTH, 1, 2),
rotorsFormat(REFLECTORS, 2, 3)
]
}, },
{ {
name: "German Service Enigma (Fourth - 4 rotor)", name: "German Service Enigma (Fourth - 4 rotor)",
value: rotorsFormat(ROTORS, 0, 8) value: [
rotorsFormat(ROTORS, 0, 8),
rotorsFormat(ROTORS_FOURTH, 1, 3),
rotorsFormat(REFLECTORS, 2, 4)
]
}, },
{ {
name: "User defined", name: "User defined",
value: "" value: ["", "", ""]
}, },
], ],
"target": 1 "target": [1, 2, 3]
}, },
{ {
name: "Main rotors", name: "Main rotors",
type: "text", type: "text",
value: "" value: ""
}, },
{
"name": "Standard Enigmas",
"type": "populateOption",
"value": [
{
name: "German Service Enigma (First - 3 rotor)",
value: ""
},
{
name: "German Service Enigma (Second - 3 rotor)",
value: ""
},
{
name: "German Service Enigma (Third - 4 rotor)",
value: rotorsFormat(ROTORS_FOURTH, 1, 2)
},
{
name: "German Service Enigma (Fourth - 4 rotor)",
value: rotorsFormat(ROTORS_FOURTH, 1, 3)
},
{
name: "User defined",
value: ""
},
],
"target": 3
},
{ {
name: "4th rotor", name: "4th rotor",
type: "text", type: "text",
value: "" value: ""
}, },
{
"name": "Standard Enigmas",
"type": "populateOption",
"value": [
{
name: "German Service Enigma (First - 3 rotor)",
value: rotorsFormat(REFLECTORS, 0, 1)
},
{
name: "German Service Enigma (Second - 3 rotor)",
value: rotorsFormat(REFLECTORS, 0, 2)
},
{
name: "German Service Enigma (Third - 4 rotor)",
value: rotorsFormat(REFLECTORS, 2, 3)
},
{
name: "German Service Enigma (Fourth - 4 rotor)",
value: rotorsFormat(REFLECTORS, 2, 4)
},
{
name: "User defined",
value: ""
},
],
"target": 5
},
{ {
name: "Reflectors", name: "Reflectors",
type: "text", type: "text",
@ -217,11 +179,11 @@ class MultipleBombe extends Operation {
*/ */
run(input, args) { run(input, args) {
const mainRotorsStr = args[1]; const mainRotorsStr = args[1];
const fourthRotorsStr = args[3]; const fourthRotorsStr = args[2];
const reflectorsStr = args[5]; const reflectorsStr = args[3];
let crib = args[6]; let crib = args[4];
const offset = args[7]; const offset = args[5];
const check = args[8]; const check = args[6];
const rotors = []; const rotors = [];
const fourthRotors = []; const fourthRotors = [];
const reflectors = []; const reflectors = [];

View file

@ -39,7 +39,7 @@ class HTMLIngredient {
*/ */
toHtml() { toHtml() {
let html = "", let html = "",
i, m; i, m, eventFn;
switch (this.type) { switch (this.type) {
case "string": case "string":
@ -142,10 +142,11 @@ class HTMLIngredient {
</div>`; </div>`;
break; break;
case "populateOption": case "populateOption":
case "populateMultiOption":
html += `<div class="form-group"> html += `<div class="form-group">
<label for="${this.id}" class="bmd-label-floating">${this.name}</label> <label for="${this.id}" class="bmd-label-floating">${this.name}</label>
<select <select
class="form-control arg" class="form-control arg no-state-change populate-option"
id="${this.id}" id="${this.id}"
arg-name="${this.name}" arg-name="${this.name}"
${this.disabled ? "disabled" : ""}>`; ${this.disabled ? "disabled" : ""}>`;
@ -155,14 +156,20 @@ class HTMLIngredient {
} else if ((m = this.value[i].name.match(/\[\/([a-z0-9 -()^]+)\]/i))) { } else if ((m = this.value[i].name.match(/\[\/([a-z0-9 -()^]+)\]/i))) {
html += "</optgroup>"; html += "</optgroup>";
} else { } else {
html += `<option populate-value="${this.value[i].value}">${this.value[i].name}</option>`; const val = this.type === "populateMultiOption" ?
JSON.stringify(this.value[i].value) :
this.value[i].value;
html += `<option populate-value='${val}'>${this.value[i].name}</option>`;
} }
} }
html += `</select> html += `</select>
${this.hint ? "<span class='bmd-help'>" + this.hint + "</span>" : ""} ${this.hint ? "<span class='bmd-help'>" + this.hint + "</span>" : ""}
</div>`; </div>`;
this.manager.addDynamicListener("#" + this.id, "change", this.populateOptionChange, this); eventFn = this.type === "populateMultiOption" ?
this.populateMultiOptionChange :
this.populateOptionChange;
this.manager.addDynamicListener("#" + this.id, "change", eventFn, this);
break; break;
case "editableOption": case "editableOption":
html += `<div class="form-group input-group"> html += `<div class="form-group input-group">
@ -248,6 +255,9 @@ class HTMLIngredient {
* @param {event} e * @param {event} e
*/ */
populateOptionChange(e) { populateOptionChange(e) {
e.preventDefault();
e.stopPropagation();
const el = e.target; const el = e.target;
const op = el.parentNode.parentNode; const op = el.parentNode.parentNode;
const target = op.querySelectorAll(".arg")[this.target]; const target = op.querySelectorAll(".arg")[this.target];
@ -260,6 +270,37 @@ class HTMLIngredient {
} }
/**
* Handler for populate multi option changes.
* Populates the relevant arguments with the specified values.
*
* @param {event} e
*/
populateMultiOptionChange(e) {
e.preventDefault();
e.stopPropagation();
const el = e.target;
const op = el.parentNode.parentNode;
const args = op.querySelectorAll(".arg");
const targets = this.target.map(i => args[i]);
const vals = JSON.parse(el.childNodes[el.selectedIndex].getAttribute("populate-value"));
const evt = new Event("change");
for (let i = 0; i < targets.length; i++) {
targets[i].value = vals[i];
}
// Fire change event after all targets have been assigned
this.manager.recipe.ingChange();
// Send change event for each target once all have been assigned, to update the label placement.
for (const target of targets) {
target.dispatchEvent(evt);
}
}
/** /**
* Handler for editable option clicks. * Handler for editable option clicks.
* Populates the input box with the selected value. * Populates the input box with the selected value.

View file

@ -205,6 +205,7 @@ class RecipeWaiter {
* @fires Manager#statechange * @fires Manager#statechange
*/ */
ingChange(e) { ingChange(e) {
if (e && e.target && e.target.classList.contains("no-state-change")) return;
window.dispatchEvent(this.manager.statechange); window.dispatchEvent(this.manager.statechange);
} }
@ -392,6 +393,15 @@ class RecipeWaiter {
this.buildRecipeOperation(item); this.buildRecipeOperation(item);
document.getElementById("rec-list").appendChild(item); document.getElementById("rec-list").appendChild(item);
// Trigger populateOption events
const populateOptions = item.querySelectorAll(".populate-option");
const evt = new Event("change", {bubbles: true});
if (populateOptions.length) {
for (const el of populateOptions) {
el.dispatchEvent(evt);
}
}
item.dispatchEvent(this.manager.operationadd); item.dispatchEvent(this.manager.operationadd);
return item; return item;
} }

View file

@ -16,9 +16,10 @@ TestRegister.addTests([
"op": "Multiple Bombe", "op": "Multiple Bombe",
"args": [ "args": [
// I, II and III // I, II and III
"User defined", "EKMFLGDQVZNTOWYHXUSPAIBRCJ<R\nAJDKSIRUXBLHWTMCQGZNPYFVOE<F\nBDFHJLCPRTXVZNYEIWGAKMUSQO<W", "User defined",
"User defined", "", "EKMFLGDQVZNTOWYHXUSPAIBRCJ<R\nAJDKSIRUXBLHWTMCQGZNPYFVOE<F\nBDFHJLCPRTXVZNYEIWGAKMUSQO<W",
"User defined", "AY BR CU DH EQ FS GL IP JX KN MO TZ VW", // B "",
"AY BR CU DH EQ FS GL IP JX KN MO TZ VW", // B
"THISISATESTMESSAGE", 0, false "THISISATESTMESSAGE", 0, false
] ]
} }
@ -35,9 +36,10 @@ TestRegister.addTests([
"op": "Multiple Bombe", "op": "Multiple Bombe",
"args": [ "args": [
// I, II and III // I, II and III
"User defined", "EKMFLGDQVZNTOWYHXUSPAIBRCJ<R\nAJDKSIRUXBLHWTMCQGZNPYFVOE<F\nBDFHJLCPRTXVZNYEIWGAKMUSQO<W", "User defined",
"User defined", "LEYJVCNIXWPBQMDRTAKZGFUHOS", // Beta "EKMFLGDQVZNTOWYHXUSPAIBRCJ<R\nAJDKSIRUXBLHWTMCQGZNPYFVOE<F\nBDFHJLCPRTXVZNYEIWGAKMUSQO<W",
"User defined", "AE BN CK DQ FU GY HW IJ LO MP RX SZ TV", // B thin "LEYJVCNIXWPBQMDRTAKZGFUHOS", // Beta
"AE BN CK DQ FU GY HW IJ LO MP RX SZ TV", // B thin
"THISISATESTMESSAGE", 0, false "THISISATESTMESSAGE", 0, false
] ]
} }