add c-operation-list so any of these elements ( category list, category list item, operation list, operation list item ) can be created individually or simply through their parent. Also fix some annotations across the app that used event instead of Event, causing the IDE to get confused

This commit is contained in:
Robin Scholtes 2023-06-16 17:08:43 +12:00
parent b1b0be254b
commit 6f6e9cce39
16 changed files with 235 additions and 197 deletions

View file

@ -66,8 +66,8 @@ class App {
document.dispatchEvent(this.manager.appstart); document.dispatchEvent(this.manager.appstart);
this.loadLocalStorage(); this.loadLocalStorage();
this.buildUI();
this.buildCategoryList(); this.buildCategoryList();
this.buildUI();
this.manager.setup(); this.manager.setup();
this.manager.output.saveBombe(); this.manager.output.saveBombe();
this.uriParams = this.getURIParams(); this.uriParams = this.getURIParams();
@ -427,23 +427,30 @@ class App {
* @param {string[]} favourites * @param {string[]} favourites
*/ */
updateFavourites(favourites) { updateFavourites(favourites) {
// @todo: probably need this elsewhere
// // Destroy the current list items we no longer need in the edit Favourites modal
// const operations = document.querySelectorAll("#editable-favourites ....");
// listItems.forEach((li => {
// li.remove();
// }))
this.saveFavourites(favourites); this.saveFavourites(favourites);
this.loadFavourites(); this.loadFavourites();
/* Rebuild only the favourites category */ /* Rebuild only the favourites category */
// double-check if the first category is indeed "catFavourites", // double-check if the first category is indeed "catFavourites",
if (document.querySelector("c-category-list > ul > c-category-li > li > a[data-target='#catFavourites']")) { if (document.querySelector("c-category-list > ul > c-category-li > li > a[data-target='#catFavourites']")) {
// then destroy // then destroy
document.querySelectorAll("c-category-list > ul > c-category-li")[0].remove(); document.querySelectorAll("c-category-list > ul > c-category-li")[0].remove();
// and rebuild it // and rebuild it
const favCatConfig = this.categories.find( catConfig => catConfig.name === "Favourites"); const favCatConfig = this.categories.find(catConfig => catConfig.name === "Favourites");
const favouriteCategory = new CCategoryLi( const favouriteCategory = new CCategoryLi(
this, this,
favCatConfig, favCatConfig,
this.operations, this.operations,
false false,
true
); );
// finally prepend it to c-category-list // finally prepend it to c-category-list
@ -777,7 +784,7 @@ class App {
* Fires whenever the input or recipe changes in any way. * Fires whenever the input or recipe changes in any way.
* *
* @listens Manager#statechange * @listens Manager#statechange
* @param {event} e * @param {Event} e
*/ */
stateChange(e) { stateChange(e) {
debounce(function() { debounce(function() {
@ -890,17 +897,18 @@ class App {
} }
/** /**
* @fires Manager#oplistcreate in nested c-category-li build() function * @fires Manager#oplistcreate from nested c-category-li > c-operation-list build() function
*/ */
buildCategoryList() { buildCategoryList() {
const categoryList = new CCategoryList( const categoryList = new CCategoryList(
this, this,
this.categories, this.categories,
this.operations this.operations,
true
); );
categoryList.build(); categoryList.build();
document.querySelector("#categories").appendChild( categoryList ); document.querySelector("#categories").appendChild(categoryList);
} }
} }

View file

@ -319,7 +319,7 @@ class HTMLIngredient {
* Handler for populate option changes. * Handler for populate option changes.
* Populates the relevant argument with the specified value. * Populates the relevant argument with the specified value.
* *
* @param {event} e * @param {Event} e
*/ */
populateOptionChange(e) { populateOptionChange(e) {
e.preventDefault(); e.preventDefault();
@ -343,7 +343,7 @@ class HTMLIngredient {
* Handler for populate multi option changes. * Handler for populate multi option changes.
* Populates the relevant arguments with the specified values. * Populates the relevant arguments with the specified values.
* *
* @param {event} e * @param {Event} e
*/ */
populateMultiOptionChange(e) { populateMultiOptionChange(e) {
e.preventDefault(); e.preventDefault();
@ -374,7 +374,7 @@ class HTMLIngredient {
* 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.
* *
* @param {event} e * @param {Event} e
*/ */
editableOptionClick(e) { editableOptionClick(e) {
e.preventDefault(); e.preventDefault();
@ -395,7 +395,7 @@ class HTMLIngredient {
* Handler for argument selector changes. * Handler for argument selector changes.
* Shows or hides the relevant arguments for this operation. * Shows or hides the relevant arguments for this operation.
* *
* @param {event} e * @param {Event} e
*/ */
argSelectorChange(e) { argSelectorChange(e) {
e.preventDefault(); e.preventDefault();

View file

@ -151,12 +151,11 @@ class Manager {
this.addMultiEventListener("#search", "keyup paste search click", this.ops.searchOperations, this.ops); this.addMultiEventListener("#search", "keyup paste search click", this.ops.searchOperations, this.ops);
this.addDynamicListener(".op-list li.operation", "dblclick", this.ops.operationDblclick, this.ops); this.addDynamicListener(".op-list li.operation", "dblclick", this.ops.operationDblclick, this.ops);
document.getElementById("close-ops-dropdown-icon").addEventListener("click", this.ops.closeOpsDropdown.bind(this.ops)); document.getElementById("close-ops-dropdown-icon").addEventListener("click", this.ops.closeOpsDropdown.bind(this.ops));
document.getElementById("edit-favourites").addEventListener("click", this.ops.editFavouritesClick.bind(this.ops)); // document.getElementById("edit-favourites").addEventListener("click", this.ops.editFavouritesClick.bind(this.ops));
document.getElementById("save-favourites").addEventListener("click", this.ops.saveFavouritesClick.bind(this.ops)); document.getElementById("save-favourites").addEventListener("click", this.ops.saveFavouritesClick.bind(this.ops));
document.getElementById("reset-favourites").addEventListener("click", this.ops.resetFavouritesClick.bind(this.ops)); document.getElementById("reset-favourites").addEventListener("click", this.ops.resetFavouritesClick.bind(this.ops));
this.addDynamicListener(".op-list", "oplistcreate", this.ops.opListCreate, this.ops); this.addDynamicListener(".op-list", "oplistcreate", this.ops.opListCreate, this.ops);
this.addDynamicListener("li.operation", "operationadd", this.recipe.opAdd, this.recipe); this.addDynamicListener("li.operation", "operationadd", this.recipe.opAdd, this.recipe);
// this.addDynamicListener(".op-icon.star-icon", "click", this.ops.onIconFavouriteClick, this.ops);
// Recipe // Recipe
this.addDynamicListener(".arg:not(select)", "input", this.recipe.ingChange, this.recipe); this.addDynamicListener(".arg:not(select)", "input", this.recipe.ingChange, this.recipe);

View file

@ -1,4 +1,4 @@
import {COperationLi} from "./c-operation-li.mjs"; import {COperationList} from "./c-operation-list.mjs";
/** /**
* c(ustom element)-category-li ( list item ) * c(ustom element)-category-li ( list item )
@ -7,38 +7,66 @@ import {COperationLi} from "./c-operation-li.mjs";
* @param {CatConf} category - The category and operations to be populated. * @param {CatConf} category - The category and operations to be populated.
* @param {Object.<string, OpConf>} operations - The list of operation configuration objects. * @param {Object.<string, OpConf>} operations - The list of operation configuration objects.
* @param {Boolean} isExpanded - expand the category on init or not * @param {Boolean} isExpanded - expand the category on init or not
* @param {Boolean} includeOpLiStarIcon - Include the left side 'star' icon to favourite an operation easily
* */ * */
export class CCategoryLi extends HTMLElement { export class CCategoryLi extends HTMLElement {
constructor( constructor(
app, app,
category, category,
operations, operations,
isExpanded isExpanded,
includeOpLiStarIcon,
) { ) {
super(); super();
this.app = app; this.app = app;
this.category = category; this.category = category; // contains a string[] of operation names under .ops
this.operations = operations; this.operations = operations; // opConfig[]
this.label = category.name; this.label = category.name;
this.isExpanded = isExpanded; this.isExpanded = isExpanded;
this.includeOpLiStarIcon = includeOpLiStarIcon;
this.build(); this.build();
this.addEventListener("click", this.handleClick.bind(this)); this.addEventListener("click", this.handleClick.bind(this));
} }
// /** /**
// * Handle click * Handle click
// * *
// * @param {Event} e * @param {Event} e
// */ */
// handleClick(e) { handleClick(e) {
// if (e.target === this.querySelector("button")) { // todo some event (target ) bs here
// // todo back to this "hitbox" issue w the icon inside the button if (e.target === this.querySelector("button")) {
// this.app.manager.ops.editFavouritesClick(e); // todo back to this "hitbox" issue w the icon inside the button
// } console.log(e.target);
// } this.app.manager.ops.editFavouritesClick(e);
}
}
/**
* Build c-category-li containing a nested c-operation-list ( op-list )
*/
build() {
const li = this.buildListItem();
const a = this.buildAnchor();
const div = this.buildCollapsablePanel();
li.appendChild(a);
li.appendChild(div);
this.appendChild(li);
const opList = new COperationList(
this.app,
this.category.ops,
this.includeOpLiStarIcon,
)
opList.build();
div.appendChild(opList);
}
/** /**
* Build the li element * Build the li element
@ -101,53 +129,6 @@ export class CCategoryLi extends HTMLElement {
return div; return div;
}; };
/**
* Build the op-list for this category
*
* @param {string[]} opNames
*/
buildOperationList(opNames) {
return opNames.map(opName => {
if (!(opName in this.operations)) {
log.warn(`${opName} could not be found.`);
return;
}
return new COperationLi(
this.app,
opName,
{
class: "check-icon",
innerText: "check"
},
this.operations[opName]
);
});
}
/**
* Build c-category-li and dispatch event oplistcreate
*/
build() {
const ul = document.createElement("ul");
ul.classList.add("op-list");
const li = this.buildListItem();
const a = this.buildAnchor();
const div = this.buildCollapsablePanel();
li.appendChild(a);
li.appendChild(div);
div.appendChild(ul);
this.appendChild(li);
this.buildOperationList(this.category.ops).forEach(operationListItem =>
ul.appendChild(operationListItem)
);
ul.dispatchEvent(this.app.manager.oplistcreate);
}
/** /**
* Append a c-operation-li to this op-list * Append a c-operation-li to this op-list
* *

View file

@ -5,15 +5,17 @@ import {CCategoryLi} from "./c-category-li.mjs";
* *
* @param {App} app - The main view object for CyberChef * @param {App} app - The main view object for CyberChef
* @param {CatConf[]} categories - The list of categories and operations to be populated. * @param {CatConf[]} categories - The list of categories and operations to be populated.
* @param {Object.<string, OpConf>} operations - The list of operation configuration objects. * @param {Object.<string, OpConf>} operations - A list of operation configuration objects.
* @param {boolean} includeOpLiStarIcon - optionally add the 'star' icon to the left of an individual operation
**/ **/
export class CCategoryList extends HTMLElement { export class CCategoryList extends HTMLElement {
constructor( app, categories, operations ) { constructor(app, categories, operations, includeOpLiStarIcon) {
super(); super();
this.app = app; this.app = app;
this.categories = categories; this.categories = categories;
this.operations = operations; this.operations = operations;
this.includeOpLiStarIcon = includeOpLiStarIcon;
} }
/** /**
@ -27,9 +29,9 @@ export class CCategoryList extends HTMLElement {
this.app, this.app,
category, category,
this.operations, this.operations,
index === 0 index === 0,
this.includeOpLiStarIcon
); );
ul.appendChild(cat); ul.appendChild(cat);
}); });

View file

@ -6,22 +6,24 @@ import url from "url";
* @param {App} app - The main view object for CyberChef * @param {App} app - The main view object for CyberChef
* @param {string} name - The name of the operation * @param {string} name - The name of the operation
* @param {Object} icon - { class: string, innerText: string } - The optional and customizable icon displayed on the right side of the operation * @param {Object} icon - { class: string, innerText: string } - The optional and customizable icon displayed on the right side of the operation
* @param {Object} config - The configuration object for this operation. * @param {Boolean} includeStarIcon - Include the left side 'star' icon to favourite an operation easily
*/ */
export class COperationLi extends HTMLElement { export class COperationLi extends HTMLElement {
constructor( constructor(
app, app,
name, name,
icon, icon,
config includeStarIcon,
) { ) {
super(); super();
this.app = app; this.app = app;
this.name = name; this.name = name;
this.isFavourite = this.app.isLocalStorageAvailable() && localStorage.favourites?.includes(name);
this.icon = icon; this.icon = icon;
this.config = config; this.includeStarIcon = includeStarIcon;
this.config = this.app.operations[name];
this.isFavourite = this.app.isLocalStorageAvailable() && localStorage.favourites?.includes(name);
this.build(); this.build();
@ -29,6 +31,8 @@ export class COperationLi extends HTMLElement {
this.addEventListener('dblclick', this.handleDoubleClick.bind(this)); this.addEventListener('dblclick', this.handleDoubleClick.bind(this));
} }
// todo: dont think I need config separately, just use this.app.operations[name].xx?
/** /**
* @fires OperationsWaiter#operationDblclick on double click * @fires OperationsWaiter#operationDblclick on double click
* @param {Event} e * @param {Event} e
@ -50,6 +54,23 @@ export class COperationLi extends HTMLElement {
} }
} }
/**
* Build c-operation-li
*/
build() {
const li = this.buildListItem();
const icon = this.buildIcon();
if ( this.includeStarIcon ){
const starIcon = this.buildStarIcon();
li.appendChild(starIcon);
}
li.appendChild(icon);
this.appendChild(li);
}
/** /**
* Given a URL for a Wikipedia (or other wiki) page, this function returns a link to that page. * Given a URL for a Wikipedia (or other wiki) page, this function returns a link to that page.
* *
@ -128,7 +149,7 @@ export class COperationLi extends HTMLElement {
} }
/** /**
* Build the star icon * Build the ( optional ) star icon
*/ */
buildStarIcon() { buildStarIcon() {
const icon = document.createElement("i"); const icon = document.createElement("i");
@ -147,20 +168,6 @@ export class COperationLi extends HTMLElement {
return icon; return icon;
} }
/**
* Build c-operation-li
*/
build() {
const li = this.buildListItem();
const icon = this.buildIcon();
const starIcon = this.buildStarIcon();
li.appendChild(icon);
li.appendChild(starIcon);
this.appendChild(li);
}
updateFavourite(isFavourite) { updateFavourite(isFavourite) {
if (isFavourite) { if (isFavourite) {
this.querySelector("li").classList.add("favourite"); this.querySelector("li").classList.add("favourite");

View file

@ -0,0 +1,45 @@
import {COperationLi} from "./c-operation-li.mjs";
/**
* c(ustom element)-operation-list
*
* @param {App} app - The main view object for CyberChef
* @param {string[]} opNames - A list of operation names
* @param {boolean} includeStarIcon - optionally add the 'star' icon to the left of the operation
* @param {Object} icon ( { class: string, innerText: string } ). check-icon by default
*/
export class COperationList extends HTMLElement {
constructor(app, opNames, includeStarIcon, icon) {
super();
this.app = app;
this.opNames = opNames;
this.includeStarIcon = includeStarIcon;
this.icon = icon;
}
build() {
const ul = document.createElement("ul");
ul.classList.add("op-list");
this.opNames.forEach((opName => {
const li = new COperationLi(
this.app,
opName,
{
class: this.icon ? this.icon.class : "check-icon",
innerText: this.icon ? this.icon.innerText : "check"
},
this.includeStarIcon
);
ul.appendChild(li);
}))
ul.dispatchEvent(this.app.manager.oplistcreate);
this.append(ul);
}
}
customElements.define("c-operation-list", COperationList);

View file

@ -142,14 +142,6 @@
<div id="preloader-error" class="loading-error"></div> <div id="preloader-error" class="loading-error"></div>
</div> </div>
<!-- End preloader overlay --> <!-- End preloader overlay -->
<!-- <button type="button"-->
<!-- class="btn btn-warning bmd-btn-icon"-->
<!-- id="edit-favourites"-->
<!-- data-toggle="tooltip"-->
<!-- title="Edit favourites">-->
<!-- <i class="material-icons">star</i>-->
<!-- </button>-->
<div id="content-wrapper"> <div id="content-wrapper">
<div id="banner"> <div id="banner">
<div> <div>
@ -591,7 +583,7 @@
<li><span style="font-weight: bold">To remove:</span> hit the delete button or drag out of the list below</li> <li><span style="font-weight: bold">To remove:</span> hit the delete button or drag out of the list below</li>
</ul> </ul>
<br> <br>
<ul id="edit-favourites-list" class="op-list"></ul> <div id="editable-favourites"></div>
<div class="option-item"> <div class="option-item">
</div> </div>
</div> </div>

View file

@ -14,17 +14,17 @@
margin-bottom: 20px; margin-bottom: 20px;
} }
#edit-favourites-list { #editable-favourites {
margin: 10px; margin: 10px;
border: 1px solid var(--op-list-operation-border-colour); border: 1px solid var(--op-list-operation-border-colour);
} }
#edit-favourites-list .operation { #editable-favourites c-operation-li > li {
border-left: none; border-left: none;
border-right: none; border-right: none;
} }
#edit-favourites-list .operation:last-child { #editable-favourites c-operation-list > li:last-child {
border-bottom: none; border-bottom: none;
} }

View file

@ -26,7 +26,7 @@ class BindingsWaiter {
* Checks whether valid keyboard shortcut has been instated * Checks whether valid keyboard shortcut has been instated
* *
* @fires Manager#statechange * @fires Manager#statechange
* @param {event} e * @param {Event} e
*/ */
parseInput(e) { parseInput(e) {
const modKey = this.app.options.useMetaKey ? e.metaKey : e.altKey; const modKey = this.app.options.useMetaKey ? e.metaKey : e.altKey;

View file

@ -347,7 +347,7 @@ class ControlsWaiter {
/** /**
* Populates the bug report information box with useful technical info. * Populates the bug report information box with useful technical info.
* *
* @param {event} e * @param {Event} e
*/ */
supportButtonClick(e) { supportButtonClick(e) {
e.preventDefault(); e.preventDefault();

View file

@ -654,7 +654,7 @@ class InputWaiter {
/** /**
* Handler for file details toggle clicks * Handler for file details toggle clicks
* @param {event} e * @param {Event} e
*/ */
toggleFileDetails(e) { toggleFileDetails(e) {
$("[data-toggle='tooltip']").tooltip("hide"); $("[data-toggle='tooltip']").tooltip("hide");
@ -838,7 +838,7 @@ class InputWaiter {
* Updates the value stored in the inputWorker * Updates the value stored in the inputWorker
* Debounces the input so we don't call autobake too often. * Debounces the input so we don't call autobake too often.
* *
* @param {event} e * @param {Event} e
* *
* @fires Manager#statechange * @fires Manager#statechange
*/ */
@ -870,7 +870,7 @@ class InputWaiter {
* Handler for input dragover events. * Handler for input dragover events.
* Gives the user a visual cue to show that items can be dropped here. * Gives the user a visual cue to show that items can be dropped here.
* *
* @param {event} e * @param {Event} e
*/ */
inputDragover(e) { inputDragover(e) {
// This will be set if we're dragging an operation // This will be set if we're dragging an operation
@ -886,7 +886,7 @@ class InputWaiter {
* Handler for input dragleave events. * Handler for input dragleave events.
* Removes the visual cue. * Removes the visual cue.
* *
* @param {event} e * @param {Event} e
*/ */
inputDragleave(e) { inputDragleave(e) {
e.stopPropagation(); e.stopPropagation();
@ -903,7 +903,7 @@ class InputWaiter {
* Handler for input drop events. * Handler for input drop events.
* Loads the dragged data. * Loads the dragged data.
* *
* @param {event} e * @param {Event} e
*/ */
async inputDrop(e) { async inputDrop(e) {
// This will be set if we're dragging an operation // This will be set if we're dragging an operation
@ -1013,7 +1013,7 @@ class InputWaiter {
* Handler for open input button events * Handler for open input button events
* Loads the opened data into the input textarea * Loads the opened data into the input textarea
* *
* @param {event} e * @param {Event} e
*/ */
inputOpen(e) { inputOpen(e) {
e.preventDefault(); e.preventDefault();
@ -1178,7 +1178,7 @@ class InputWaiter {
/** /**
* Handler for clicking on a tab * Handler for clicking on a tab
* *
* @param {event} mouseEvent * @param {Event} mouseEvent
*/ */
changeTabClick(mouseEvent) { changeTabClick(mouseEvent) {
if (!mouseEvent.target) return; if (!mouseEvent.target) return;
@ -1361,7 +1361,7 @@ class InputWaiter {
/** /**
* Handler for clicking on a remove tab button * Handler for clicking on a remove tab button
* *
* @param {event} mouseEvent * @param {Event} mouseEvent
*/ */
removeTabClick(mouseEvent) { removeTabClick(mouseEvent) {
if (!mouseEvent.target) { if (!mouseEvent.target) {
@ -1376,7 +1376,7 @@ class InputWaiter {
/** /**
* Handler for scrolling on the input tabs area * Handler for scrolling on the input tabs area
* *
* @param {event} wheelEvent * @param {Event} wheelEvent
*/ */
scrollTab(wheelEvent) { scrollTab(wheelEvent) {
wheelEvent.preventDefault(); wheelEvent.preventDefault();
@ -1509,7 +1509,7 @@ class InputWaiter {
/** /**
* Handle when an option in the filter drop down box is clicked * Handle when an option in the filter drop down box is clicked
* *
* @param {event} mouseEvent * @param {Event} mouseEvent
*/ */
filterOptionClick(mouseEvent) { filterOptionClick(mouseEvent) {
document.getElementById("input-filter-button").innerText = mouseEvent.target.innerText; document.getElementById("input-filter-button").innerText = mouseEvent.target.innerText;
@ -1542,7 +1542,7 @@ class InputWaiter {
/** /**
* Handler for clicking on a filter result * Handler for clicking on a filter result
* *
* @param {event} e * @param {Event} e
*/ */
filterItemClick(e) { filterItemClick(e) {
if (!e.target) return; if (!e.target) return;

View file

@ -7,6 +7,9 @@
import HTMLOperation from "../HTMLOperation.mjs"; import HTMLOperation from "../HTMLOperation.mjs";
import Sortable from "sortablejs"; import Sortable from "sortablejs";
import {fuzzyMatch, calcMatchRanges} from "../../core/lib/FuzzyMatch.mjs"; import {fuzzyMatch, calcMatchRanges} from "../../core/lib/FuzzyMatch.mjs";
import {COperationLi} from "../components/c-operation-li.mjs";
import {CCategoryList} from "../components/c-category-list.mjs";
import {COperationList} from "../components/c-operation-list.mjs";
/** /**
* Waiter to handle events related to the operations. * Waiter to handle events related to the operations.
@ -32,7 +35,7 @@ class OperationsWaiter {
* Handler for search events. * Handler for search events.
* Finds operations which match the given search term and displays them under the search box. * Finds operations which match the given search term and displays them under the search box.
* *
* @param {event} e * @param {Event} e
*/ */
searchOperations(e) { searchOperations(e) {
let ops, selected; let ops, selected;
@ -180,7 +183,7 @@ class OperationsWaiter {
* Handler for oplistcreate events. * Handler for oplistcreate events.
* *
* @listens Manager#oplistcreate * @listens Manager#oplistcreate
* @param {event} e * @param {Event} e
*/ */
opListCreate(e) { opListCreate(e) {
if (this.app.isMobileView()) { if (this.app.isMobileView()) {
@ -228,7 +231,7 @@ class OperationsWaiter {
* Handler for operation doubleclick events. * Handler for operation doubleclick events.
* Adds the operation to the recipe and auto bakes. * Adds the operation to the recipe and auto bakes.
* *
* @param {event} e * @param {Event} e
*/ */
operationDblclick(e) { operationDblclick(e) {
const li = e.target; const li = e.target;
@ -240,56 +243,59 @@ class OperationsWaiter {
* Handler for edit favourites click events. * Handler for edit favourites click events.
* Sets up the 'Edit favourites' pane and displays it. * Sets up the 'Edit favourites' pane and displays it.
* *
* @param {event} e // * @param {Event} e
*/ */
editFavouritesClick(e) { editFavouritesClick() {
e.preventDefault(); // Get list of Favourite operation names
e.stopPropagation(); const favCatConfig = this.app.categories.find(catConfig => catConfig.name === "Favourites");
const div = document.getElementById("editable-favourites");
// Add favourites to modal if(favCatConfig !== undefined) {
const favCat = this.app.categories.filter(function(c) { const opList = new COperationList(
return c.name === "Favourites"; this.app,
})[0]; favCatConfig.ops,
false,
{
class: "remove-icon",
innerText: "delete"
}
)
let html = ""; opList.build();
for (let i = 0; i < favCat.ops.length; i++) {
const opName = favCat.ops[i]; div.appendChild(opList);
const operation = new HTMLOperation(opName, this.app.operations[opName], this.app, this.manager);
html += operation.toStubHtml(true);
} }
const editFavouritesList = document.getElementById("edit-favourites-list"); // this.removeIntent = false;
editFavouritesList.innerHTML = html; //
this.removeIntent = false; // const editableList = Sortable.create(ul, {
// filter: ".remove-icon",
// onFilter: function (evt) {
// const el = editableList.closest(evt.item);
// if (el && el.parentNode) {
// $(el).popover("dispose");
// el.parentNode.removeChild(el);
// }
// },
// onEnd: function(evt) {
// if (this.removeIntent) {
// $(evt.item).popover("dispose");
// evt.item.remove();
// }
// }.bind(this),
// });
//
// Sortable.utils.on(ul, "dragleave", function() {
// this.removeIntent = true;
// }.bind(this));
//
// Sortable.utils.on(ul, "dragover", function() {
// this.removeIntent = false;
// }.bind(this));
const editableList = Sortable.create(editFavouritesList, { // if (!this.app.isMobileView()) {
filter: ".remove-icon", // $("#editable-favourites [data-toggle=popover]").popover();
onFilter: function (evt) { // }
const el = editableList.closest(evt.item);
if (el && el.parentNode) {
$(el).popover("dispose");
el.parentNode.removeChild(el);
}
},
onEnd: function(evt) {
if (this.removeIntent) {
$(evt.item).popover("dispose");
evt.item.remove();
}
}.bind(this),
});
Sortable.utils.on(editFavouritesList, "dragleave", function() {
this.removeIntent = true;
}.bind(this));
Sortable.utils.on(editFavouritesList, "dragover", function() {
this.removeIntent = false;
}.bind(this));
if (!this.app.isMobileView()) {
$("#edit-favourites-list [data-toggle=popover]").popover();
}
$("#favourites-modal").modal(); $("#favourites-modal").modal();
} }
@ -329,10 +335,10 @@ class OperationsWaiter {
* Saves the selected favourites and reloads them. * Saves the selected favourites and reloads them.
*/ */
saveFavouritesClick() { saveFavouritesClick() {
const favs = document.querySelectorAll("#edit-favourites-list li"); const listItems = document.querySelectorAll("#editable-favourites c-operation-li > li");
const favouritesList = Array.from(favs, e => e.childNodes[0].textContent); const favourites = Array.from(listItems, li => li.getAttribute("data-name"));
this.app.updateFavourites(favouritesList); this.app.updateFavourites(favourites);
} }

View file

@ -57,7 +57,7 @@ class OptionsWaiter {
* Handler for options click events. * Handler for options click events.
* Displays the options pane. * Displays the options pane.
* *
* @param {event} e * @param {Event} e
*/ */
optionsClick(e) { optionsClick(e) {
e.preventDefault(); e.preventDefault();
@ -77,7 +77,7 @@ class OptionsWaiter {
/** /**
* Handler for switch change events. * Handler for switch change events.
* *
* @param {event} e * @param {Event} e
*/ */
switchChange(e) { switchChange(e) {
const el = e.target; const el = e.target;
@ -91,7 +91,7 @@ class OptionsWaiter {
/** /**
* Handler for number change events. * Handler for number change events.
* *
* @param {event} e * @param {Event} e
*/ */
numberChange(e) { numberChange(e) {
const el = e.target; const el = e.target;
@ -105,7 +105,7 @@ class OptionsWaiter {
/** /**
* Handler for select change events. * Handler for select change events.
* *
* @param {event} e * @param {Event} e
*/ */
selectChange(e) { selectChange(e) {
const el = e.target; const el = e.target;

View file

@ -982,7 +982,7 @@ class OutputWaiter {
/** /**
* Handler for changing tabs event * Handler for changing tabs event
* *
* @param {event} mouseEvent * @param {Event} mouseEvent
*/ */
changeTabClick(mouseEvent) { changeTabClick(mouseEvent) {
if (!mouseEvent.target) return; if (!mouseEvent.target) return;
@ -996,7 +996,7 @@ class OutputWaiter {
/** /**
* Handler for scrolling on the output tabs area * Handler for scrolling on the output tabs area
* *
* @param {event} wheelEvent * @param {Event} wheelEvent
*/ */
scrollTab(wheelEvent) { scrollTab(wheelEvent) {
wheelEvent.preventDefault(); wheelEvent.preventDefault();
@ -1510,7 +1510,7 @@ class OutputWaiter {
* Handler for clicking on a filter result. * Handler for clicking on a filter result.
* Changes to the clicked output * Changes to the clicked output
* *
* @param {event} e * @param {Event} e
*/ */
filterItemClick(e) { filterItemClick(e) {
if (!e.target) return; if (!e.target) return;

View file

@ -125,7 +125,7 @@ class RecipeWaiter {
* at the appropriate place and initialises it. * at the appropriate place and initialises it.
* *
* @fires Manager#operationadd * @fires Manager#operationadd
* @param {event} evt * @param {Event} evt
*/ */
opSortEnd(evt) { opSortEnd(evt) {
if (this.removeIntent && evt.item.parentNode.id === "rec-list") { if (this.removeIntent && evt.item.parentNode.id === "rec-list") {
@ -158,7 +158,7 @@ class RecipeWaiter {
* If the element being dragged is an operation, displays a visual cue so that the user knows it can * If the element being dragged is an operation, displays a visual cue so that the user knows it can
* be dropped here. * be dropped here.
* *
* @param {event} e * @param {Event} e
*/ */
favDragover(e) { favDragover(e) {
if (e.dataTransfer.effectAllowed !== "move") if (e.dataTransfer.effectAllowed !== "move")
@ -183,7 +183,7 @@ class RecipeWaiter {
* Handler for favourite dragleave events. * Handler for favourite dragleave events.
* Removes the visual cue. * Removes the visual cue.
* *
* @param {event} e * @param {Event} e
*/ */
favDragleave(e) { favDragleave(e) {
e.stopPropagation(); e.stopPropagation();
@ -196,7 +196,7 @@ class RecipeWaiter {
* Handler for favourite drop events. * Handler for favourite drop events.
* Adds the dragged operation to the favourites list. * Adds the dragged operation to the favourites list.
* *
* @param {event} e * @param {Event} e
*/ */
favDrop(e) { favDrop(e) {
e.stopPropagation(); e.stopPropagation();
@ -224,7 +224,7 @@ class RecipeWaiter {
* Updates the icon status. * Updates the icon status.
* *
* @fires Manager#statechange * @fires Manager#statechange
* @param {event} e * @param {Event} e
*/ */
disableClick(e) { disableClick(e) {
const icon = e.target; const icon = e.target;
@ -249,7 +249,7 @@ class RecipeWaiter {
* Updates the icon status. * Updates the icon status.
* *
* @fires Manager#statechange * @fires Manager#statechange
* @param {event} e * @param {Event} e
*/ */
breakpointClick(e) { breakpointClick(e) {
const bp = e.target; const bp = e.target;
@ -271,7 +271,7 @@ class RecipeWaiter {
* Removes the operation from the recipe and auto bakes. * Removes the operation from the recipe and auto bakes.
* *
* @fires Manager#statechange * @fires Manager#statechange
* @param {event} e * @param {Event} e
*/ */
operationDblclick(e) { operationDblclick(e) {
e.target.remove(); e.target.remove();
@ -284,7 +284,7 @@ class RecipeWaiter {
* Removes the operation from the recipe. * Removes the operation from the recipe.
* *
* @fires Manager#statechange * @fires Manager#statechange
* @param {event} e * @param {Event} e
*/ */
operationChildDblclick(e) { operationChildDblclick(e) {
e.target.parentNode.remove(); e.target.parentNode.remove();
@ -409,7 +409,6 @@ class RecipeWaiter {
item.dispatchEvent(this.manager.operationadd); item.dispatchEvent(this.manager.operationadd);
this.manager.ops.updateListItemsClasses("#rec-list", "selected"); this.manager.ops.updateListItemsClasses("#rec-list", "selected");
console.log("operation add");
return item; return item;
} }
@ -433,7 +432,7 @@ class RecipeWaiter {
* Handler for operation dropdown events from toggleString arguments. * Handler for operation dropdown events from toggleString arguments.
* Sets the selected option as the name of the button. * Sets the selected option as the name of the button.
* *
* @param {event} e * @param {Event} e
*/ */
dropdownToggleClick(e) { dropdownToggleClick(e) {
e.stopPropagation(); e.stopPropagation();
@ -470,7 +469,7 @@ class RecipeWaiter {
* *
* @listens Manager#operationadd * @listens Manager#operationadd
* @fires Manager#statechange * @fires Manager#statechange
* @param {event} e * @param {Event} e
*/ */
opAdd(e) { opAdd(e) {
log.debug(`'${e.target.getAttribute("data-name")}' added to recipe`); log.debug(`'${e.target.getAttribute("data-name")}' added to recipe`);
@ -486,13 +485,12 @@ class RecipeWaiter {
* *
* @listens Manager#operationremove * @listens Manager#operationremove
* @fires Manager#statechange * @fires Manager#statechange
* @param {event} e * @param {Event} e
*/ */
opRemove(e) { opRemove(e) {
log.debug("Operation removed from recipe"); log.debug("Operation removed from recipe");
window.dispatchEvent(this.manager.statechange); window.dispatchEvent(this.manager.statechange);
this.manager.ops.updateListItemsClasses("#rec-list", "selected"); this.manager.ops.updateListItemsClasses("#rec-list", "selected");
console.log("operation remove");
} }
@ -500,7 +498,7 @@ class RecipeWaiter {
* Handler for text argument dragover events. * Handler for text argument dragover events.
* Gives the user a visual cue to show that items can be dropped here. * Gives the user a visual cue to show that items can be dropped here.
* *
* @param {event} e * @param {Event} e
*/ */
textArgDragover (e) { textArgDragover (e) {
// This will be set if we're dragging an operation // This will be set if we're dragging an operation
@ -517,7 +515,7 @@ class RecipeWaiter {
* Handler for text argument dragleave events. * Handler for text argument dragleave events.
* Removes the visual cue. * Removes the visual cue.
* *
* @param {event} e * @param {Event} e
*/ */
textArgDragLeave (e) { textArgDragLeave (e) {
e.stopPropagation(); e.stopPropagation();
@ -530,7 +528,7 @@ class RecipeWaiter {
* Handler for text argument drop events. * Handler for text argument drop events.
* Loads the dragged data into the argument textarea. * Loads the dragged data into the argument textarea.
* *
* @param {event} e * @param {Event} e
*/ */
textArgDrop(e) { textArgDrop(e) {
// This will be set if we're dragging an operation // This will be set if we're dragging an operation