Skip to content

fix: downgrade scratch-blocks from v2.0.3 to v1.3.0 to restore custom block argument dragging#271

Merged
takaokouji merged 8 commits into
developfrom
fix/downgrade-scratch-blocks-v1.3.0
Mar 11, 2026
Merged

fix: downgrade scratch-blocks from v2.0.3 to v1.3.0 to restore custom block argument dragging#271
takaokouji merged 8 commits into
developfrom
fix/downgrade-scratch-blocks-v1.3.0

Conversation

@takaokouji
Copy link
Copy Markdown

@takaokouji takaokouji commented Mar 10, 2026

Summary

scratch-blocks v2.0.0(spork ブランチ)の導入により、「定義」ブロックの引数がドラッグできなくなる致命的な不具合が発生。scratch-blocks を v2.0.3 → v1.3.0 にダウングレードし、関連する全ての変更を巻き戻す。

Fixes #270
Related: smalruby/smalruby3-develop#74

Changes Made

  • Phase 1: upstream ソースファイル 22個を pre-spork 状態(2cec3ae79)へ復元。blocks.jsx は pre-merge Smalruby 状態(fe2bee4d3)、blocks.js は Smalruby gesture recovery マーカーを維持
  • Phase 2: scratch-blocks を v2.0.3 → v1.3.0 にダウングレード。react/react-dom/redux の直接依存を削除
  • Phase 3: Smalruby v2 適応コード 8コミット分を巻き戻し(Ruby converter の API、blocks-screenshot、vm-listener-hoc、eslint config、Jest config)
  • Phase 4: upstream テスト/設定ファイル 22個を pre-spork 状態へ復元(v1 DOM セレクター、テスト期待値、設定ファイル)
  • Phase 5: ビルド・テスト確認 — lint パス、build:dev 成功、ユニットテスト全パス(42 GUI + 729 Ruby + 226 VM)
  • Phase 6: ブラウザ動作確認 — エディター正常起動(0エラー)、定義ブロック作成・引数追加動作確認

Implementation Steps

  • Phase 1: upstream ソースファイルの pre-spork 復元
  • Phase 2: scratch-blocks ダウングレード + 依存関係修正
  • Phase 3: Smalruby v2 適応コードの巻き戻し
  • Phase 4: upstream テスト/設定ファイルの pre-spork 復元
  • Phase 5: ビルド・テスト確認
  • Phase 6: ブラウザ動作確認

Test Plan

  • lint パス(warnings のみ、errors なし)
  • build:dev 成功
  • ユニットテスト パス(42 GUI + 729 Ruby converter + 226 VM)
  • 統合テスト パス(CI で実行)
  • ブラウザ確認: 定義ブロック引数追加動作確認済み

🤖 Generated with Claude Code

takaokouji and others added 7 commits March 11, 2026 01:50
… v1.3.0)

Restore 22 upstream source files to their state at commit 2cec3ae
(before the spork merge that introduced scratch-blocks v2.0.0).

- blocks.jsx: restored to pre-merge Smalruby state (fe2bee4) which
  includes all Smalruby features on top of pre-spork upstream code
- blocks.js: restored to pre-spork upstream + re-added Smalruby gesture
  recovery markers
- radix-ui-context-menu.js: restored (was deleted by spork)
- 19 other files: direct restoration to 2cec3ae

Part of #270 Phase 1.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- scratch-gui: scratch-blocks 2.0.3 → 1.3.0
- scratch-vm: scratch-blocks 2.0.3 → 1.3.0
- Remove react, react-dom, redux direct deps added for v2 compatibility
- Regenerate package-lock.json

Part of #270 Phase 2.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Revert changes from 8 Smalruby commits that adapted code for
scratch-blocks v2.0.0:

- Ruby converter: restore `import Blockly from` (not `import * as`),
  `Blockly.utils.genUid()` (not idGenerator), v1 API calls
- generator.js, ruby-generator/index.js: restore pre-v2 state
- block-display-modal.jsx: restore pre-v2 state
- blocks-screenshot.js: remove v2 bounding box, CSS transform, and
  text color fixes
- vm-listener-hoc.jsx: remove v2 keyboard event handling
- eslint.config.mjs: remove redux ignore (no longer a direct dep)
- package.json: remove scratch-blocks from Jest transform/ignore patterns
- Restore tutorial screenshots to pre-v2 versions
- Restore unit tests to pre-v2 state

Part of #270 Phase 3.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Restore test and configuration files to their pre-spork state
(scratch-blocks v1.3.0 compatible):

- Integration tests: restore v1 DOM selectors (.blocklyToolboxDiv),
  clickText for category clicks, pre-v2 test expectations
- Unit tests: restore color-modes, define-dynamic-block, empty-block,
  monitor snapshot, engine_adapter, extension_conversion tests
- VM tests: restore stack-click, project_changed_state_blocks, events.json
- Config: restore release.config.js, tsconfig.eslint.json, webpack.config.js
- selenium-helper.js: restore pre-merge state

Part of #270 Phase 4.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Several files restored to 2cec3ae (upstream pre-spork) in Phase 1
had Smalruby-specific additions that were lost. Restore them to
fe2bee4 (pre-merge Smalruby state) instead:

- backpack.jsx: localStorage handling + @smalruby import
- make-toolbox-xml.js: onlyBlocks filtering feature (229 lines)
- define-dynamic-block.js: @smalruby import
- blocks.js (VM): parent block undefined safety check
- runtime.js (VM): BEFORE_STEP event, remove EXTENSION_DATA_LOADING
- radix-ui-context-menu.js: remove unused eslint-disable directive
- Remove dark/__mocks__ and default/__mocks__ (not in Smalruby)

All lint passes, all affected unit tests pass (42 GUI + 729 Ruby + 226 VM).

Part of #270 Phase 5.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- webpack.config.js: use require.resolve for scratch-blocks media path
  (v1.3.0 is installed in packages/scratch-gui/node_modules/, not root)
- make-toolbox-xml.js: restore to fe2bee4 with onlyBlocks filtering
- backpack.jsx: restore localStorage handling + @smalruby import
- blocks.js (VM): restore parent block undefined safety check
- runtime.js (VM): restore BEFORE_STEP event, remove EXTENSION_DATA_LOADING
- Remove dark/__mocks__ and default/__mocks__ (not in Smalruby)

Browser verified: editor loads with 0 errors, all block categories
visible, custom block creation with arguments works correctly.

Part of #270 Phase 5-6.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The VM playground webpack config copies scratch-blocks/media but used
a hardcoded ../../node_modules path. With scratch-blocks v1.3.0 not
hoisted to root node_modules, use require.resolve to find the actual
package location. Also restore module exports order (playgroundBuilder
first for webpack-dev-server).

Part of #270.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

… icons

- Align screenshot button position with Blockly zoom controls (right: 22px)
- Align Ruby tab zoom controls with Code tab zoom controls (right: 22px, bottom: 22px)
- Restore tutorial images (chat1-basic2-2, chat1-basic2-5) to develop versions
  with visible input field text
- Fix screenshot export missing green flag and rotation mark icons by inlining
  relative SVG image hrefs as data URIs before blob serialization

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@takaokouji takaokouji merged commit 7c8ade3 into develop Mar 11, 2026
9 checks passed
@takaokouji takaokouji deleted the fix/downgrade-scratch-blocks-v1.3.0 branch March 11, 2026 01:18
github-actions Bot pushed a commit that referenced this pull request Mar 11, 2026
…-scratch-blocks-v1.3.0

fix: downgrade scratch-blocks from v2.0.3 to v1.3.0 to restore custom block argument dragging
takaokouji added a commit that referenced this pull request Mar 11, 2026
Record scratch-blocks v2→v1.3.0 downgrade (PR #271) as a post-merge revert
in .upstream-merge-history.json so the next upstream merge can handle
affected files correctly.

Update upstream-merge skill (SKILL.md, phase1, phase2, phase4) to:
- Document postMergeReverts JSON schema
- Check for reverts in Phase 1 and prompt user for resolution strategy
- Add conflict resolution guidance for both "accept upstream" and
  "maintain revert" strategies in Phase 2
- Handle postMergeReverts cleanup in Phase 4

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
takaokouji added a commit that referenced this pull request May 3, 2026
In scratch-blocks v1 toolbox.getWidth() returned the combined width of
the category column and the flyout, so the PaletteToggle sat on the
right edge of the open palette as intended (matches the existing
docs/block-editor/screenshots/0101-overview-1280x800.png and
docs/mobile-ui/screenshots/02-code-palette-open.png).

In scratch-blocks v2 toolbox.getWidth() returns only the
category-column width (61px in the SP layout), so the toggle ended
up sandwiched between the categories and the flyout.

Fixed by adding the flyout width (workspace.getFlyout().getWidth())
on top of the toolbox width when computing the toggle's left offset.

Verified at 844x390 and 1280x800: the ◀ toggle now sits on the
right edge of the open palette.

Note: when scratch-blocks was originally upgraded in PR #271 we hit
a similar issue and ended up downgrading; this time the v2 API is
stable enough that the right fix is to use the new shape rather than
revert.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
takaokouji added a commit that referenced this pull request May 3, 2026
When the v1 downgrade was reverted (Smalruby PR #271, commit 5e51637),
three scratch-blocks v2 adaptations to blocks-screenshot.js were rolled
back along with everything else. Now that we are back on v2 they need
to come back, otherwise the camera-icon screenshot button silently
breaks (or, depending on the workspace state, throws "drawImage on
canvas with width or height of 0").

Re-applied:

1. **getBlocksBoundingBox return shape** — v2 returns
   {top, bottom, left, right} instead of v1's {x, y, width, height}.
   Normalise to the {x, y, width, height} shape the rest of the module
   expects. Without this, calculateCanvasDimensions multiplied undefined
   by scale and produced a 0×0 canvas.

2. **Theme classes on exported SVG** — copy
   workspace.getInjectionDiv().className onto the exported <svg>
   element so v2's theme-scoped CSS selectors
   (".scratch-renderer.default-theme .blocklyText") match. Without
   this, block text renders in the wrong colour.

3. **Clear inherited CSS transform on canvas clones** — v2 positions
   the block / bubble canvases via style.transform (e.g.
   "translate(311px, 0px) scale(0.675)") instead of the SVG transform
   attribute v1 used. We need to clear style.transform on the clone
   so it doesn't override the SVG transform attribute we set for
   export positioning.

Verified end-to-end with Playwright:
- adding a "when flag clicked" block + invoking downloadBlocksAsImage
  now downloads test_sprite.png with the block correctly rendered
  inside a padded white canvas.
- 21 unit tests in test/unit/lib/blocks-screenshot.test.js pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
takaokouji added a commit that referenced this pull request May 3, 2026
Two more pieces of the PR #271 v2-adaptation revert needed to come back
now that we are on scratch-blocks v2.1.19:

1. Blockly.utils.genUid() is now Blockly.utils.idGenerator.genUid().
   In v1 the helper lived directly on utils; v2 moved it under
   utils.idGenerator. Updated 9 call sites in
   ruby-to-blocks-converter (block-creation, my-blocks,
   variable-utils) and block-display-modal. The Ruby tab failed at
   runtime ("scratch_blocks__WEBPACK_IMPORTED_MODULE_0__.utils.genUid
   is not a function") whenever it tried to round-trip Ruby → blocks
   because every block / variable / comment ID generation went
   through this helper.

2. scratch-gui jest config: scratch-blocks v2 ships dist/main.mjs as
   ESM, so jest needs to babel-transform it. Re-added scratch-blocks
   to:
   - transform: matched files: node_modules/(@bjorn3/browser_wasi_shim
     |@ruby/prism|scratch-blocks)/.*\.m?js$
   - transformIgnorePatterns: allow-list scratch-blocks
   Without this, 203 of 303 unit-test suites failed at import time
   with "SyntaxError: Cannot use import statement outside a module".

Both adaptations were originally added when scratch-blocks first
went to v2.0.x and then rolled back in PR #271's downgrade
(commit 5e51637, "fix: revert Smalruby v2 adaptation code to
v1.3.0 compatible state"). Re-applying them as-is now that v2 is
back.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
takaokouji added a commit that referenced this pull request May 3, 2026
The unit-test side of PR #271's "v2 → v1 revert" needs to come back
now that scratch-blocks is on v2.1.19. Tests that were silently
running on v1 mocks/expectations after the revert have been
updated to match the actual v2 code.

- color-modes.test.js: replaced inline mock with upstream's
  __mocks__/index.js auto-mocking (so test data uses colourPrimary
  / colourSecondary / colourTertiary keys consistent with v2).
  Re-added the missing __mocks__ files that PR #271 deleted.
- backpack.test.jsx: rewritten to mock storage.backpackStorage.list
  directly instead of stubbing backpackApi.getBackpackContents.
  After the v2 refactor in containers/backpack.jsx, the dispatch
  goes through storage.backpackStorage which routes localStorage
  to getBackpackContents inside LegacyBackpackStorage.
- libraries/costumes.json + sprites.json: removed 21 trademarked
  costume entries (Cat-a/Cat-b/etc.) and 8 trademarked sprite
  entries (Cat, Cat Flying, Gobo, Pico, Nano, etc.) that the
  upstream merge re-introduced. removed-trademarks.test.js was
  already in the Smalruby tree to enforce this; it had been
  failing because the merge re-added the trademarked names.
- scratch-vm extensions / VM tests: ran eslint --fix to drop the
  now-unused "// eslint-disable-next-line @stylistic/max-len"
  directives the upstream merge brought in.
- backpack.test.jsx + a few other files: ran prettier --write to
  match Smalruby's tabWidth: 4 + trailing comma style.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
takaokouji added a commit that referenced this pull request May 3, 2026
…#271 revert

Many integration tests referenced v1 toolbox DOM selectors
(.blocklyToolboxDiv, .scratchCategoryMenuItem, .scratchCategoryId-X)
that don't exist in scratch-blocks v2. After PR #271 reverted these
to v1 names alongside the v1 downgrade, they need to come back to
their v2 form now that we are on v2.1.19.

selenium-helper.js: replaced wholesale with upstream v13.7.2's
version (which has the v2 helpers — scopeForBlockId,
scopeForBlockText, scopeForCategoryId, scopeForCategoryText,
scopeForFlyoutBlock, clickBlocksCategory, etc.) and re-applied
the Smalruby additions:

- jest.retryTimes(1) for flaky CI runs
- IS_ROOT_USER + --no-sandbox flag for containerised CI
- this.until exposed
- waitForLoadingFinished / notExistsByXpath / urlFor helpers
- getDriver retries up to 2 times on session-start failure
- _buildChromeCapabilities split out of getDriver

Integration test files:
- menu-bar.test.js: high-contrast color check now selects the
  category bubble via scopeForCategoryId('motion') + .categoryBubble
  instead of .scratchCategoryMenuItem.scratchCategoryId-motion.
- sprites.test.js: switch to clickBlocksCategory('Motion') for the
  toolbox category click (clickText hits a label that is not the
  click-receiving element in v2).
- block-palette.test.js: .blocklyToolboxDiv → .blocklyToolbox.
- dncl-mode-validation.test.js: same renames as above plus
  .scratchCategoryMenuItem → .blocklyToolboxCategory.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
takaokouji added a commit that referenced this pull request May 4, 2026
…ks v2

Ruby → blocks 変換で生成される `@ruby:method:*` などの内部メタデータ
コメントが、scratch-blocks v2 (Blockly v12) では minimize 表示されず、
全コメントが同じ workspace 座標 (200, 0) にスタックして workspace の
別の場所に浮いていた。

これは PR #271 の v1 ダウングレードで対応していなかった v2 仕様変更:

1. v1 の `comment.setMinimized(true)` API は v2 で廃止され、ブロック付随
   コメントは block の **comment icon** として実装された
   (`block.getIcons()` から `IconType.comment` を取得して操作)
2. icon の `setBubbleVisible(false)` で minimize できるが、Events.disable
   中に呼ぶと no-op、また onWorkspaceUpdate 直後の同期呼び出しは Blockly
   の post-load render に上書きされる → 100ms 遅延 + block ID から再取得
   する必要がある
3. v2 は collapsed (minimized) 状態でも comment.x/y を保持するため、
   converter が常に (200, 0) を割り当てると複数の bubble が完全に重なる
   → block ごとに `setBubbleLocation(blockX + 220, blockY)` で再配置

加えて scratch-vm 側で `block.x` が undefined の topLevel block の XML
出力が `x="undefined"` になり、scratch-blocks v2 がこれを 0 として読み込み
move event を発火、`fromRuby` 検出 (`typeof topBlock.x === 'undefined'`)
が効かなくなっていた問題も修正。`Number.isFinite` で実値があるときだけ
属性を出力するようガードを追加。

修正後:
- `puts "hello"` 1 行 → 該当 say block 横に minimize されたバッジ表示
- `puts "a"` + `puts "b"` 複数 → 各 block にバッジが正しく分離して表示
- `def/return` を含むコードでも `@ruby:return` マーカー付き block は
  既存の getTopComments 経路で処理され従来通り動作
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix: downgrade scratch-blocks from v2.0.3 to v1.3.0 to restore custom block argument dragging

1 participant