feat: add Ruby String extension with delete/delete! blocks#362
Open
takaokouji wants to merge 30 commits intodevelopfrom
Open
feat: add Ruby String extension with delete/delete! blocks#362takaokouji wants to merge 30 commits intodevelopfrom
takaokouji wants to merge 30 commits intodevelopfrom
Conversation
Add procedures_call pattern for dynamic argument reconstruction: - parseBlockText: parse block text into label/arg components - disconnectOldBlocks/removeAllInputs: save connections and clear inputs - createAllInputs: manual input construction with appendValueInput - updateBlockDisplay: pause rendering → rebuild → re-render - setupMethodValidator: dropdown validator for method-driven arg changes Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New VM extension smalruby_ruby with: - stringMethodR (REPORTER): String#delete returning a new string - stringMethodC (COMMAND): String#delete! for in-place mutation - Dynamic arguments support via argumentsByMethod/menuItems - Japanese translations (ja, ja-Hira) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- stringMethodR (REPORTER): generates "str".delete("l") code
- stringMethodC (COMMAND): generates "str".delete!("l")\n code
- Supports optional ARG2 for future expansion
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- String#delete → ruby_stringMethodR (REPORTER) - String#delete! → ruby_stringMethodC (COMMAND) - Supports string, block, and variable receivers Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Generator tests: string method code generation with mocked valueToCode - Converter tests: Ruby code → blocks conversion for delete/delete! - Tests cover string/variable receivers, invalid args, wrong arg count Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The _isRubyBlock check in the converter rejects all blocks with opcodes starting with ruby_ (ruby_statement, ruby_expression). Rename extension ID from 'ruby' to 'smalrubyRuby' so opcodes become smalrubyRuby_*. Also fix lint errors in define-dynamic-block.js (indent, no-undefined, prefer-arrow-callback). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
🚀 Preview deployed: https://smalruby.jp/smalruby3-editor/feat/ruby-string-extension/ |
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Without setupTranslations(), format-message cannot find Japanese translations, causing block conversion to fail when the extension is auto-loaded from the Ruby tab. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
isDynamic blocks require blockInfo in their mutation data so that domToMutation can reconstruct the block's inputs. Without this, the block is created but all inputs (STRING, ARG1, METHOD) are ignored by scratch-blocks. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
mutationToXML expects blockInfo to be an object (it calls JSON.stringify internally). Passing a pre-stringified value caused double-encoding and broke domToMutation parsing. Also remove debug logging from define-dynamic-block.js. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add smalrubyRuby extension to extension library with icon and translations - Restrict delete! converter to variable-only receivers (bang methods modify in place, so string literals are not valid receivers) - Update tests accordingly Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Fix _isRubyBlock regex to match only fallback ruby blocks (ruby_statement, ruby_expression, ruby_range, etc.) instead of all opcodes starting with ruby_. This allows the Ruby extension to use the simpler 'ruby' ID without conflicting with fallback blocks. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
delete! requires a variable receiver, so 'hello world' as default is misleading. Use empty string instead. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Change delete! block's STRING from input_value to variableNames menu - Add getVariableNamesMenuItems to Ruby extension (koshien pattern) - stringMethodC now looks up the variable by name and modifies its value - Generator uses getFieldValue + variableNameByName for variable receiver - Converter uses lookupVariableFromVariableBlock + addField for variable name Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When a menu (like variableNames) uses a dynamic items function, it won't be in menuItems. Fall back to a single-option dropdown with the default value so the field_dropdown is still created. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When dragging a block from the toolbox, the XML parser creates shadow blocks after domToMutation. If createAllInputs also creates shadows via respawnShadow_(), they become orphaned and float on the workspace. Skip shadow creation on the first domToMutation call (isFirstCall=true) and let the XML parser handle it. Only create shadows during validator-triggered rebuilds (method dropdown changes). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Dynamic menus (like variableNames with items: 'getVariableNamesMenuItems') were not resolved in isDynamic blocks because createAllInputs only checked blockInfo.menuItems. Now falls back to categoryInfo.menuInfo where runtime has already bound the menu function. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Proves variable-length arguments work: - delete/delete!: 1 argument (pattern) - gsub/gsub!: 2 arguments (pattern, replacement) Dropdown selection dynamically changes the number of input slots. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
All Smalruby extensions use the smalruby prefix convention. Revert _isRubyBlock to original regex since smalrubyRuby_ opcodes don't match /^ruby_/. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Wrap ternary in arrow function with parentheses. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The translation keys in translations.json were already updated to smalrubyRuby.* but the formatMessage IDs in index.js were still using ruby.*, causing missing translation warnings. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Use the official Ruby logo (diamond + "Ruby" text) as the block icon for the smalrubyRuby extension, following the koshien pattern. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Follow the scratch3_core_example.js pattern: encode SVG icons as data:image/svg+xml,%3Csvg... (URL-encoded) instead of base64. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The original Adobe Illustrator SVG contained DOCTYPE/ENTITY declarations that prevented rendering as a data URI. Cleaned the SVG by removing XML declaration, DOCTYPE, metadata, and Adobe-specific attributes, then resolving entity references. Source SVG is stored alongside index.js for maintainability. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
isDynamic blocks use createAllInputs instead of the standard runtime conversion, so the extension icon (field_image + field_vertical_separator) was not being prepended. Now createAllInputs checks categoryInfo.blockIconURI and adds the icon fields at the start of the block. Also clean up the source SVG (remove DOCTYPE/ENTITY/metadata) for proper data URI rendering, and store the clean source alongside index.js. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The cleaned SVG still contained a:midPointStop elements which caused the SVG to fail parsing as a data URI, showing a broken image icon. Also removed i:knockout attributes. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add disableMonitor: true to stringMethodR (REPORTER) block to remove the flyout checkbox, matching koshien extension pattern - Change STRING defaultValue from 'hello world' to '' for both delete and gsub value blocks Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Change default values from empty/'l'/'r' to 'string'/'arg1'/'arg2' so the block displays meaningful placeholder text instead of 'undefined' or cryptic single characters. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
delete/delete!blocks (feat: add Ruby String extension with delete/delete! blocks and dynamic arguments #360)Changes Made
define-dynamic-block.jswithargumentsByMethodsupport for dynamic argument count based on dropdown selectionsmalruby_ruby(ID:smalrubyRuby) withstringMethodR(REPORTER) andstringMethodC(COMMAND)"str".delete("l"),"str".delete!("l"))Implementation Steps (from #360)
define-dynamic-block.jsextension (argumentsByMethod)Notable Decisions
rubytosmalrubyRubybecause the converter's_isRubyBlock()rejects all blocks with opcodes matching/^ruby_/(used forruby_statement,ruby_expressionfallback blocks)Test Plan
Closes #360