diff --git a/src/web/App.mjs b/src/web/App.mjs index f66dd9b6..6ce0940d 100755 --- a/src/web/App.mjs +++ b/src/web/App.mjs @@ -908,7 +908,7 @@ class App { */ buildCategoryList() { // double-check if the c-category-list already exists, - if (document.querySelector("#categories > c-category-list")){ + if (document.querySelector("#categories > c-category-list")) { // then destroy it document.querySelector("#categories > c-category-list").remove(); } diff --git a/src/web/components/c-category-li.mjs b/src/web/components/c-category-li.mjs index 5826f61f..da8330f3 100644 --- a/src/web/components/c-category-li.mjs +++ b/src/web/components/c-category-li.mjs @@ -2,15 +2,16 @@ import {COperationList} from "./c-operation-list.mjs"; /** * c(ustom element)-category-li ( list item ) - * - * @param {App} app - The main view object for CyberChef - * @param {CatConf} category - The category and operations to be populated. - * @param {Object.} operations - The list of operation configuration objects. - * @param {Boolean} isExpanded - expand the category by default on init or not - * @param {Boolean} includeOpLiStarIcon - Include the left side 'star' icon to each of the c-category-li > - * c-operation-list > c-operation-li list items in this category - * */ + */ export class CCategoryLi extends HTMLElement { + /** + * @param {App} app - The main view object for CyberChef + * @param {CatConf} category - The category and operations to be populated. + * @param {Object.} operations - The list of operation configuration objects. + * @param {Boolean} isExpanded - expand the category by default on init or not + * @param {Boolean} includeOpLiStarIcon - Include the left side 'star' icon to each of the c-category-li > + * c-operation-list > c-operation-li list items in this category + */ constructor( app, category, @@ -65,11 +66,11 @@ export class CCategoryLi extends HTMLElement { const opList = new COperationList( this.app, - this.category.ops.map( op => [op]), + this.category.ops.map(op => [op]), this.includeOpLiStarIcon, false, true - ) + ); opList.build(); @@ -85,7 +86,7 @@ export class CCategoryLi extends HTMLElement { li.classList.add("category"); return li; - }; + } /** * Build the anchor element @@ -100,7 +101,7 @@ export class CCategoryLi extends HTMLElement { a.innerText = this.label; - if (this.label === "Favourites"){ + if (this.label === "Favourites") { const editFavouritesButton = this.buildEditFavouritesButton(a); // Note: I'm leaving this here as it was in the code originally, but it's not doing anything and it didn't @@ -118,12 +119,12 @@ export class CCategoryLi extends HTMLElement { } return a; - }; + } /** * Build the collapsable panel that contains the op-list for this category */ - buildCollapsablePanel(){ + buildCollapsablePanel() { const div = document.createElement("div"); div.setAttribute("id", `${"cat" + this.label.replace(/[\s/\-:_]/g, "")}`); @@ -137,7 +138,7 @@ export class CCategoryLi extends HTMLElement { } return div; - }; + } /** * If this category is Favourites, build and return the star icon button diff --git a/src/web/components/c-category-list.mjs b/src/web/components/c-category-list.mjs index efbb47ca..cdc2759a 100644 --- a/src/web/components/c-category-list.mjs +++ b/src/web/components/c-category-list.mjs @@ -2,15 +2,21 @@ import {CCategoryLi} from "./c-category-li.mjs"; /** * c(ustom element)-category-list - * - * @param {App} app - The main view object for CyberChef - * @param {CatConf[]} categories - The list of categories and operations to be populated. - * @param {Object.} operations - A list of operation configuration objects. - * @param {Boolean} includeOpLiStarIcon - Include the left side 'star' icon to each of the c-category-li > - * c-operation-list > c-operation-li list items in this c-category-list - **/ + */ export class CCategoryList extends HTMLElement { - constructor(app, categories, operations, includeOpLiStarIcon) { + /** + * @param {App} app - The main view object for CyberChef + * @param {CatConf[]} categories - The list of categories and operations to be populated. + * @param {Object.} operations - A list of operation configuration objects. + * @param {Boolean} includeOpLiStarIcon - Include the left side 'star' icon to each of the c-category-li > + * c-operation-list > c-operation-li list items in this c-category-list + */ + constructor( + app, + categories, + operations, + includeOpLiStarIcon + ) { super(); this.app = app; diff --git a/src/web/components/c-ingredient-li.mjs b/src/web/components/c-ingredient-li.mjs index 1d0aaa17..44edc770 100644 --- a/src/web/components/c-ingredient-li.mjs +++ b/src/web/components/c-ingredient-li.mjs @@ -6,13 +6,18 @@ import HTMLIngredient from "../HTMLIngredient.mjs"; * Note: This is the #recipe-list list item component, not to be confused with HTMLIngredient which make up the smaller * components of this list item. It would be good to eventually fuse that code into this component or alternatively, to * turn that into a separate native web component . - * - * @param {App} app - The main view object for CyberChef - * @param {string} name - The operation ( or aka ingredient- in this context ) name - * @param {object[]} args - The args properties of the operation ( see operation config file ) - * */ + */ export class CIngredientLi extends HTMLElement { - constructor(app, name, args = []) { + /** + * @param {App} app - The main view object for CyberChef + * @param {string} name - The operation ( or aka ingredient- in this context ) name + * @param {object[]} args - The args properties of the operation ( see operation config file ) + */ + constructor( + app, + name, + args = [] + ) { super(); this.app = app; @@ -38,12 +43,11 @@ export class CIngredientLi extends HTMLElement { /** * Handle double click - * * @param {Event} e */ handleDoubleClick(e) { // do not remove if icons or form elements are double clicked - if ( e.target === this.querySelector("li") || e.target === this.querySelector("div.op-title") ) { + if (e.target === this.querySelector("li") || e.target === this.querySelector("div.op-title")) { this.remove(); } } @@ -64,13 +68,13 @@ export class CIngredientLi extends HTMLElement { ingredientDiv.classList.add("ingredients"); li.appendChild(titleDiv); - li.appendChild(ingredientDiv) + li.appendChild(ingredientDiv); for (let i = 0; i < this.args.length; i++) { ingredientDiv.innerHTML += (this.args[i].toHtml()); } - const icons = this.buildIcons(); + const icons = this.buildIcons(); const clearfixDiv = document.createElement("div"); diff --git a/src/web/components/c-operation-li.mjs b/src/web/components/c-operation-li.mjs index da77a926..ddc6e314 100644 --- a/src/web/components/c-operation-li.mjs +++ b/src/web/components/c-operation-li.mjs @@ -2,16 +2,17 @@ import url from "url"; /** * c(ustom element)-operation-li ( list item ) - * - * @param {App} app - The main view object for CyberChef - * @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 {Boolean} includeStarIcon - Include the left-side 'star' icon to favourite an operation - * @param {[number[]]} charIndicesToHighlight - optional array of indices that indicate characters to highlight (bold) - * in the operation name, for instance when the user searches for an operation by typing */ export class COperationLi extends HTMLElement { + /** + * @param {App} app - The main view object for CyberChef + * @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 {Boolean} includeStarIcon - Include the left-side 'star' icon to favourite an operation + * @param {[number[]]} charIndicesToHighlight - optional array of indices that indicate characters to highlight (bold) + * in the operation name, for instance when the user searches for an operation by typing + */ constructor( app, name, @@ -87,9 +88,9 @@ export class COperationLi extends HTMLElement { * * @param {HTMLElement} el */ - handlePopover(el){ + handlePopover(el) { // never display popovers on mobile on this component - if (this.app.isMobileView()){ + if (this.app.isMobileView()) { $(el).popover("disable"); } else { $(el).popover("enable"); @@ -105,7 +106,7 @@ export class COperationLi extends HTMLElement { const li = this.buildListItem(); const icon = this.buildIcon(); - if ( this.includeStarIcon ){ + if (this.includeStarIcon) { const starIcon = this.buildStarIcon(); li.appendChild(starIcon); } @@ -134,16 +135,16 @@ export class COperationLi extends HTMLElement { $(".popover").on("mouseleave", function () { $(_this).popover("hide"); }); - }).on("mouseleave", function () { - const _this = this; - setTimeout(function() { - // Determine if the popover associated with this element is being hovered over - if ($(_this).data("bs.popover") && - ($(_this).data("bs.popover").tip && !$($(_this).data("bs.popover").tip).is(":hover"))) { - $(_this).popover("hide"); - } - }, 50); - }); + }) + .on("mouseleave", function () { + const _this = this; + setTimeout(function() { + // Determine if the popover associated with this element is being hovered over + if ($(_this).data("bs.popover") && ($(_this).data("bs.popover").tip && !$($(_this).data("bs.popover").tip).is(":hover"))) { + $(_this).popover("hide"); + } + }, 50); + }); } /** @@ -180,7 +181,7 @@ export class COperationLi extends HTMLElement { buildListItem() { const li = document.createElement("li"); - li.appendChild( this.buildOperationName() ); + li.appendChild(this.buildOperationName()); li.setAttribute("data-name", this.name); li.classList.add("operation"); @@ -190,7 +191,7 @@ export class COperationLi extends HTMLElement { } - if (this.config.description){ + if (this.config.description) { let dataContent = this.config.description; if (this.config.infoURL) { @@ -234,7 +235,7 @@ export class COperationLi extends HTMLElement { icon.classList.add("op-icon"); icon.classList.add("star-icon"); - if (this.isFavourite){ + if (this.isFavourite) { icon.innerText = "star"; } else { icon.innerText = "star_outline"; @@ -261,7 +262,7 @@ export class COperationLi extends HTMLElement { */ cloneNode() { const { app, name, icon, includeStarIcon, charIndicesToHighlight } = this; - return new COperationLi( app, name, icon, includeStarIcon, charIndicesToHighlight ); + return new COperationLi(app, name, icon, includeStarIcon, charIndicesToHighlight); } @@ -270,7 +271,7 @@ export class COperationLi extends HTMLElement { * or simply sets the name in the span element */ buildOperationName() { - const span = document.createElement('span'); + const span = document.createElement("span"); if (this.charIndicesToHighlight.length) { let opName = "", diff --git a/src/web/components/c-operation-list.mjs b/src/web/components/c-operation-list.mjs index 62fcdcd9..92fca0d5 100644 --- a/src/web/components/c-operation-list.mjs +++ b/src/web/components/c-operation-list.mjs @@ -3,15 +3,17 @@ import Sortable from "sortablejs"; /** * c(ustom element)-operation-list - * - * @param {App} app - The main view object for CyberChef - * @param {[string, number[]]} operations - A list of operation names and indexes of characters to highlight - * @param {Boolean} includeOpLiStarIcon - Include the left side 'star' icon to each of the c-category-li > - * c-operation-list > c-operation-li list items in this c-category-list - * - * @param {Object} icon ( { class: string, innerText: string } ). check-icon by default */ export class COperationList extends HTMLElement { + /** + * @param {App} app - The main view object for CyberChef + * @param {[string, number[]]} operations - A list of operation names and indexes of characters to highlight + * @param {Boolean} includeStarIcon - Include the left side 'star' icon to each of the c-category-li > + * c-operation-list > c-operation-li list items in this c-category-list + * @param {Boolean} isSortable - List items may be sorted ( reordered ). False by default + * @param {Boolean} isCloneable - List items are cloneable to a target list. True by default + * @param {Object} icon ( { class: string, innerText: string } ). 'check-icon' by default + */ constructor( app, operations, @@ -50,19 +52,19 @@ export class COperationList extends HTMLElement { ); ul.appendChild(cOpLi); - })) + })); if (this.isSortable) { this.createSortableList(ul); } else if (!this.app.isMobileView() && this.isCloneable) { - this.createCloneableList(ul, "recipe", "rec-list"); // target name and id can be component params if needed to make it reusable + this.createCloneableList(ul, "recipe", "rec-list"); } this.append(ul); } /** - * Create a sortable ( not cloneable ) list + * Create a sortable ( but not cloneable ) list * * @param { HTMLElement } ul * */ diff --git a/src/web/waiters/OperationsWaiter.mjs b/src/web/waiters/OperationsWaiter.mjs index 9d5cb70e..8bd1bf1b 100755 --- a/src/web/waiters/OperationsWaiter.mjs +++ b/src/web/waiters/OperationsWaiter.mjs @@ -6,7 +6,6 @@ import {fuzzyMatch, calcMatchRanges} from "../../core/lib/FuzzyMatch.mjs"; import {COperationList} from "../components/c-operation-list.mjs"; -import {COperationLi} from "../components/c-operation-li.mjs"; /** * Waiter to handle events related to the operations. @@ -194,10 +193,10 @@ class OperationsWaiter { // Get list of Favourite operation names const favCatConfig = this.app.categories.find(catConfig => catConfig.name === "Favourites"); - if(favCatConfig !== undefined) { + if (favCatConfig !== undefined) { const opList = new COperationList( this.app, - favCatConfig.ops.map( op => [op]), + favCatConfig.ops.map(op => [op]), false, true, false, @@ -205,7 +204,7 @@ class OperationsWaiter { class: "remove-icon", innerText: "delete" }, - ) + ); opList.build(); div.appendChild(opList); diff --git a/src/web/waiters/RecipeWaiter.mjs b/src/web/waiters/RecipeWaiter.mjs index 6ff2f37a..c2303c55 100755 --- a/src/web/waiters/RecipeWaiter.mjs +++ b/src/web/waiters/RecipeWaiter.mjs @@ -34,9 +34,18 @@ class RecipeWaiter { initDragAndDrop() { const recList = document.getElementById("rec-list"); - let swapThreshold = this.app.isMobileView() ? 0.60 : 0.10; - let animation = this.app.isMobileView() ? 400 : 200; - let delay = this.app.isMobileView() ? 200 : 0; + let swapThreshold, animation, delay; + + // tweak these values for better user experiences per device type and UI + if (this.app.isMobileView()) { + swapThreshold = 0.60; + animation = 400; + delay = 200; + } else { + swapThreshold = 0.10; + animation = 200; + delay = 0; + } // Recipe list Sortable.create(recList, { @@ -365,7 +374,7 @@ class RecipeWaiter { * @param {string} name - The name of the operation to add */ addOperation(name) { - let item = this.buildRecipeOperation(name); + const item = this.buildRecipeOperation(name); document.getElementById("rec-list").appendChild(item); $(item).find("[data-toggle='tooltip']").tooltip();