diff --git a/plugins/toolbox-search/src/block_searcher.ts b/plugins/toolbox-search/src/block_searcher.ts index bc4e989dca..5be6d23399 100644 --- a/plugins/toolbox-search/src/block_searcher.ts +++ b/plugins/toolbox-search/src/block_searcher.ts @@ -20,6 +20,7 @@ export class BlockSearcher { * scenes, it creates a workspace, loads the specified block types on it, * indexes their types and human-readable text, and cleans up after * itself. + * * @param blockTypes A list of block types to index. */ indexBlocks(blockTypes: string[]) { @@ -29,28 +30,54 @@ export class BlockSearcher { this.indexBlockText(blockType.replaceAll('_', ' '), blockType); block.inputList.forEach((input) => { input.fieldRow.forEach((field) => { + this.indexDropdownOption(field, blockType); this.indexBlockText(field.getText(), blockType); }); }); }); } + /** + * Check if the field is a dropdown, and index every text in the option + * + * @param field We need to check the type of field + * @param blockType The block type to associate the trigrams with. + */ + private indexDropdownOption(field: Blockly.Field, blockType: string) { + if (field instanceof Blockly.FieldDropdown) { + field.getOptions(true).forEach((option) => { + if (typeof option[0] === 'string') { + this.indexBlockText(option[0], blockType); + } else if ('alt' in option[0]) { + this.indexBlockText(option[0].alt, blockType); + } + }); + } + } + /** * Filters the available blocks based on the current query string. + * * @param query The text to use to match blocks against. * @returns A list of block types matching the query. */ blockTypesMatching(query: string): string[] { - return [...this.generateTrigrams(query).map((trigram) => { - return this.trigramsToBlocks.get(trigram) ?? new Set(); - }).reduce((matches, current) => { - return this.getIntersection(matches, current); - }).values()]; + return [ + ...this.generateTrigrams(query) + .map((trigram) => { + return this.trigramsToBlocks.get(trigram) ?? new Set(); + }) + .reduce((matches, current) => { + return this.getIntersection(matches, current); + }) + .values(), + ]; } /** * Generates trigrams for the given text and associates them with the given * block type. + * * @param text The text to generate trigrams of. * @param blockType The block type to associate the trigrams with. */ @@ -64,6 +91,7 @@ export class BlockSearcher { /** * Generates a list of trigrams for a given string. + * * @param input The string to generate trigrams of. * @returns A list of trigrams of the given string. */ @@ -82,6 +110,7 @@ export class BlockSearcher { /** * Returns the intersection of two sets. + * * @param a The first set. * @param b The second set. * @returns The intersection of the two sets. @@ -89,4 +118,4 @@ export class BlockSearcher { private getIntersection(a: Set, b: Set): Set { return new Set([...a].filter((value) => b.has(value))); } -} +} \ No newline at end of file diff --git a/plugins/toolbox-search/src/toolbox_search.ts b/plugins/toolbox-search/src/toolbox_search.ts index f263314822..87c8f6cbdc 100644 --- a/plugins/toolbox-search/src/toolbox_search.ts +++ b/plugins/toolbox-search/src/toolbox_search.ts @@ -161,6 +161,38 @@ export class ToolboxSearchCategory extends Blockly.ToolboxCategory { this.flyoutItems_ = query ? this.blockSearcher.blockTypesMatching(query).map( (blockType) => { + + // create a new workspace not to disturb the current workspace + // as creation of a block may trigger other changes as adding variables + const options = {}; + const workspace = new Blockly.WorkspaceSvg( + new Blockly.Options(options)); + const block = workspace.newBlock(blockType); + const inputs = block.inputList; + + for (const input of inputs) { + const fields = input.fieldRow; + for (const field of fields) { + if (field instanceof Blockly.FieldDropdown) { + const options = field.getOptions(); + for (const option of options) { + // check if the query is in the option + // make sure the option is text + if (typeof option[0] === 'string' && + option[0].toLowerCase().includes( + query.toLowerCase())) { + const fields = {} + fields[field.name] = option[1] + return { + kind: 'block', + type: blockType, + fields: fields + }; + }; + }; + }; + }; + }; return { kind: 'block', type: blockType,