Skip to content

fix(dncl): multi-arg display, suppress furigana in DNCL, hide @ruby comment bubbles#665

Merged
takaokouji merged 11 commits into
developfrom
fix/dncl-mode-display-furigana-comments
May 10, 2026
Merged

fix(dncl): multi-arg display, suppress furigana in DNCL, hide @ruby comment bubbles#665
takaokouji merged 11 commits into
developfrom
fix/dncl-mode-display-furigana-comments

Conversation

@takaokouji
Copy link
Copy Markdown

Summary

DNCL モード関連の3件の不具合を修正:

  1. 表示する(i, " ", Data[i]) の引数が一部しか表示されない

    • Ruby→Blocks 変換で、(i.to_s + " ") + Data[i].to_s のような連鎖した文字列結合の外側 +operator_add になっていた。math + ハンドラは receiver が operator_join ブロックの場合 null を返し、string + ハンドラに委ねるよう修正。
  2. DNCL モードでもふりがなが表示される

    • localStorage で dnclMode=true の状態でリロードすると、Ruby tab でふりがなが描画されていた。初期 state を localStorage で抑制し、renderFurigana() / scheduleFuriganaUpdate()dnclModeRef ガードを追加。モード切替時にもクリア/復元。
  3. コードタブ遷移時に @ruby: メタデータコメントが第1ブロックと重なる

    • Blockly v12 で attached comment の collapsed 状態が「テキスト付き水平バー」として表示されるようになり、配列リテラル等で大量に積み重なっていた。
    • data-smalruby-meta 属性 + 注入 CSS でメタデータのみのコメントを display:none に。
    • ユーザーコメントは @ruby:comment_position:inline マーカーより前に並べることで、collapsed プレビューにユーザーテキストが表示されるよう変更(generator は行ごとにフィルタするため round-trip に影響なし)。

Test plan

  • Lint pass (eslint --max-warnings 0)
  • DNCL 関連 unit tests 70 件 pass (display-multi-arg / roundtrip / v2-example / say-block-roundtrip)
  • Operators / comments unit tests 150 件 pass
  • Furigana annotator + ruby-tab tests 349 件 pass
  • Playwright 手動検証:
    • DNCL 表示する(i, " ", Data[i]) を変換すると 4 個の looks_sayforsecs MESSAGE 入力が operator_join (text concat) になる
    • DNCL モード localStorage で reload → Ruby 入力でふりがな zone/widget/decoration が 0 個
    • DNCL → コードタブ遷移時、可視コメントは「演算子÷は商の整数値を返す」のユーザーコメントのみ
  • CI pass

🤖 Generated with Claude Code

…ruby metadata bubbles

- Ruby→Blocks: chained `+` of `operator_join` results now produces
  another `operator_join` instead of `operator_add`, so DNCL
  `表示する(i, " ", Data[i])` actually shows all three arguments.
- DNCL mode: furigana annotations are skipped when the editor shows
  Japanese pseudo-code (initial state respects localStorage; render
  paths guard on `dnclModeRef`; mode toggle clears/restores).
- Block workspace: Blockly v12 renders attached collapsed comments as
  visible bars, which cluttered the workspace with `@ruby:*` metadata
  (e.g. 11 bars stacked above the first block for a 10-element array
  literal). Hide metadata-only comments via injected CSS, and reorder
  user-merged comments to put user text first so the collapsed preview
  bar shows the user's text.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 8, 2026

takaokouji and others added 10 commits May 9, 2026 07:30
Attached comment x/y was always (0,0) by default. Blockly v11 ignored
saved values and auto-positioned bubbles at the block anchor, so this
went unnoticed. Blockly v12 treats x/y as workspace absolute
coordinates, so every metadata bubble would render at the workspace
origin in any viewer that doesn't apply the Smalruby hide-CSS — most
notably scratch.mit.edu when opening a Smalruby-saved .sb3.

Walk each comment's blockId up to the topLevel ancestor and arrange
the comments in a vertical strip 350 px to the right of that block,
35 px apart. Value-block-attached comments use the same logic via the
parent chain. User comments share the same arrangement so they sit
next to the block they describe.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Disable the CSS rule that hides metadata bubbles so we can visually
verify the new x/y positioning (which is what scratch.mit.edu will
show when opening a Smalruby-saved sb3). Will be reverted before
merging.
Replace the previous (rejected) approach that placed every comment
sequentially below the topLevel block. Instead, walk each comment's
blockId up the parent chain to the nearest non-value (statement/hat)
block, count its hops from the topLevel ancestor, and seed the
comment's x/y at (topLevel.x + 350, topLevel.y + depth * 48).

Why this matches Blockly's natural anchor:
- Statement-block comments land near the matching block in the chain
  (e.g. the 11 array-literal annotations no longer share a single y).
- Value-block comments inherit the position of their enclosing
  statement, which is where Blockly would render them anyway.
- Multiple comments anchored to the same statement still cluster, but
  near that block — not at the workspace origin.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
When several comments anchor to the same non-value block (e.g. the
multiple value-block annotations on a single looks_sayforsecs), the
prior block-anchor layout placed them all at the same coordinate and
they visually merged into one bubble in viewers without the
metadata-hide CSS.

Add per-anchor index (24, 16) offsets so each subsequent comment slides
diagonally down-right from its peers. Single-anchor comments are
untouched.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Drop the previous depth*48 approximation in target-applier — it
diverged from Blockly's actual rendering for deep chains, so the
deferred setBubbleLocation snap (whose distance heuristic only
suppresses ≤100px drift) would jump those bubbles to the
approximated coordinate, often off-screen.

Instead, after the comment icon's bubble is constructed at its
natural anchor, capture that position via getRelativeToSurfaceXY()
and write it directly to target.comments[id].x/y. The capture runs
once on the next tick and once at the end of the post-load suppress
window, so we get the final layout regardless of which timing wins.
This makes the saved sb3 reflect exactly where the bubble visually
appeared in Smalruby — viewers without the metadata-hide CSS (e.g.
scratch.mit.edu) open with bubbles next to their attached blocks.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Three call sites in looks.js explicitly passed x=200, y=0 to
createComment for puts/say variants. With the natural-anchor
capture in comment-icon-patch, this hardcoded coordinate caused
those bubbles to be created at (200, 0) — far enough from the
looks_sayforsecs's actual anchor that the deferred
setBubbleLocation snap fired and pinned them at (200, 0)
instead of the natural rendering position.

Drop the hardcoded coords; the icon patch will write the true
rendered position into the VM after the bubble settles, so
saved sb3 files and scratch.mit.edu reopens place these
bubbles next to the say block they describe.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
All five extra arguments matched _createComment's defaults. Keeping
just (text, blockId) makes the call sites consistent with the rest
of the converter and clarifies that no specific position or pin
state is intended — natural-anchor capture handles positioning.
Re-enable the rule that was temporarily disabled while verifying
bubble x/y placement. Now that natural-anchor capture writes the
true rendered position into the VM, the saved sb3 places bubbles
correctly in scratch.mit.edu, and Smalruby itself can hide them
with the CSS rule.
@takaokouji takaokouji merged commit bd22766 into develop May 10, 2026
9 checks passed
@takaokouji takaokouji deleted the fix/dncl-mode-display-furigana-comments branch May 10, 2026 01:46
github-actions Bot pushed a commit that referenced this pull request May 10, 2026
…-display-furigana-comments

fix(dncl): multi-arg display, suppress furigana in DNCL, hide @ruby comment bubbles
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.

1 participant