From 24a966d1374bd4bc5c846c2e4cdd12eef2d7b733 Mon Sep 17 00:00:00 2001 From: Koen van Wijk Date: Wed, 4 Oct 2023 14:34:12 +0200 Subject: [PATCH 1/4] Add indexing of dropdown entries --- plugins/toolbox-search/src/block_searcher.ts | 14 ++++++++ plugins/toolbox-search/src/toolbox_search.ts | 36 ++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/plugins/toolbox-search/src/block_searcher.ts b/plugins/toolbox-search/src/block_searcher.ts index bc4e989dca..e780a1deec 100644 --- a/plugins/toolbox-search/src/block_searcher.ts +++ b/plugins/toolbox-search/src/block_searcher.ts @@ -30,6 +30,20 @@ export class BlockSearcher { block.inputList.forEach((input) => { input.fieldRow.forEach((field) => { this.indexBlockText(field.getText(), blockType); + // Index the text of dropdown options. + // check if this is a dropdown + if (field instanceof Blockly.FieldDropdown) { + // get the options + const options = field.getOptions(); + // iterate through the options + options.forEach((option) => { + // index the text of the option + // only add the option[0] if it is text + if (typeof option[0] === 'string') { + this.indexBlockText(option[0], blockType); + } + }); + } }); }); }); diff --git a/plugins/toolbox-search/src/toolbox_search.ts b/plugins/toolbox-search/src/toolbox_search.ts index f263314822..6b16bd1e70 100644 --- a/plugins/toolbox-search/src/toolbox_search.ts +++ b/plugins/toolbox-search/src/toolbox_search.ts @@ -161,9 +161,45 @@ export class ToolboxSearchCategory extends Blockly.ToolboxCategory { this.flyoutItems_ = query ? this.blockSearcher.blockTypesMatching(query).map( (blockType) => { + // check the block if it has dropdowns + // get the block + const block = this.workspace_.newBlock(blockType); + // get the inputs + const inputs = block.inputList; + // iterate through the inputs + for (let input of inputs) { + // get the fields + const fields = input.fieldRow; + // iterate through the fields + for (let field of fields) { + // check if the field is a dropdown + if (field instanceof Blockly.FieldDropdown) { + // get the options + const options = field.getOptions(); + // iterate through the options + for (let 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())) { + + let fields = {} + fields[field.name] = option[1] + return { + kind: 'block', + type: blockType, + fields: fields + }; + } + }; + } + } + } + return { kind: 'block', type: blockType, + }; }) : []; From 0aecc1b5fb2c3375d2a3227ec63f16fd57b30c0f Mon Sep 17 00:00:00 2001 From: Koen van Wijk Date: Wed, 4 Oct 2023 14:34:12 +0200 Subject: [PATCH 2/4] feat: add indexing of dropdown entries --- plugins/toolbox-search/src/block_searcher.ts | 14 ++++++++ plugins/toolbox-search/src/toolbox_search.ts | 36 ++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/plugins/toolbox-search/src/block_searcher.ts b/plugins/toolbox-search/src/block_searcher.ts index bc4e989dca..e780a1deec 100644 --- a/plugins/toolbox-search/src/block_searcher.ts +++ b/plugins/toolbox-search/src/block_searcher.ts @@ -30,6 +30,20 @@ export class BlockSearcher { block.inputList.forEach((input) => { input.fieldRow.forEach((field) => { this.indexBlockText(field.getText(), blockType); + // Index the text of dropdown options. + // check if this is a dropdown + if (field instanceof Blockly.FieldDropdown) { + // get the options + const options = field.getOptions(); + // iterate through the options + options.forEach((option) => { + // index the text of the option + // only add the option[0] if it is text + if (typeof option[0] === 'string') { + this.indexBlockText(option[0], blockType); + } + }); + } }); }); }); diff --git a/plugins/toolbox-search/src/toolbox_search.ts b/plugins/toolbox-search/src/toolbox_search.ts index f263314822..6b16bd1e70 100644 --- a/plugins/toolbox-search/src/toolbox_search.ts +++ b/plugins/toolbox-search/src/toolbox_search.ts @@ -161,9 +161,45 @@ export class ToolboxSearchCategory extends Blockly.ToolboxCategory { this.flyoutItems_ = query ? this.blockSearcher.blockTypesMatching(query).map( (blockType) => { + // check the block if it has dropdowns + // get the block + const block = this.workspace_.newBlock(blockType); + // get the inputs + const inputs = block.inputList; + // iterate through the inputs + for (let input of inputs) { + // get the fields + const fields = input.fieldRow; + // iterate through the fields + for (let field of fields) { + // check if the field is a dropdown + if (field instanceof Blockly.FieldDropdown) { + // get the options + const options = field.getOptions(); + // iterate through the options + for (let 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())) { + + let fields = {} + fields[field.name] = option[1] + return { + kind: 'block', + type: blockType, + fields: fields + }; + } + }; + } + } + } + return { kind: 'block', type: blockType, + }; }) : []; From 79ae8d61acda8443f0f89dd59efc4fc0a7c82213 Mon Sep 17 00:00:00 2001 From: Koen van Wijk Date: Tue, 28 Nov 2023 22:54:11 +0100 Subject: [PATCH 3/4] Removed side events from creation of a block --- plugins/toolbox-search/src/toolbox_search.ts | 42 +++++++++----------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/plugins/toolbox-search/src/toolbox_search.ts b/plugins/toolbox-search/src/toolbox_search.ts index 6b16bd1e70..87c8f6cbdc 100644 --- a/plugins/toolbox-search/src/toolbox_search.ts +++ b/plugins/toolbox-search/src/toolbox_search.ts @@ -161,45 +161,41 @@ export class ToolboxSearchCategory extends Blockly.ToolboxCategory { this.flyoutItems_ = query ? this.blockSearcher.blockTypesMatching(query).map( (blockType) => { - // check the block if it has dropdowns - // get the block - const block = this.workspace_.newBlock(blockType); - // get the inputs + + // 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; - // iterate through the inputs - for (let input of inputs) { - // get the fields + + for (const input of inputs) { const fields = input.fieldRow; - // iterate through the fields - for (let field of fields) { - // check if the field is a dropdown + for (const field of fields) { if (field instanceof Blockly.FieldDropdown) { - // get the options const options = field.getOptions(); - // iterate through the options - for (let option of options) { + 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())) { - - let fields = {} + 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, - }; }) : []; From 059292c62f7dd55dd6ae96d8654ca8a8500d9ab2 Mon Sep 17 00:00:00 2001 From: Koen van Wijk Date: Tue, 28 Nov 2023 23:09:43 +0100 Subject: [PATCH 4/4] Undo changes to the block_searcher.ts --- plugins/toolbox-search/src/block_searcher.ts | 55 +++++++++++++------- 1 file changed, 35 insertions(+), 20 deletions(-) diff --git a/plugins/toolbox-search/src/block_searcher.ts b/plugins/toolbox-search/src/block_searcher.ts index e780a1deec..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,42 +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); - // Index the text of dropdown options. - // check if this is a dropdown - if (field instanceof Blockly.FieldDropdown) { - // get the options - const options = field.getOptions(); - // iterate through the options - options.forEach((option) => { - // index the text of the option - // only add the option[0] if it is text - if (typeof option[0] === 'string') { - this.indexBlockText(option[0], 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. */ @@ -78,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. */ @@ -96,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. @@ -103,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