Skip to content

fix: 折り畳まれたコメントへのアンカーリンクが効くようにする#9624

Merged
machida merged 7 commits intomainfrom
fix/anchor-link-to-folded-comments
Feb 10, 2026
Merged

fix: 折り畳まれたコメントへのアンカーリンクが効くようにする#9624
machida merged 7 commits intomainfrom
fix/anchor-link-to-folded-comments

Conversation

@machida
Copy link
Copy Markdown
Member

@machida machida commented Feb 6, 2026

Issue

概要

ページ読み込み時にURLのハッシュが#comment_で始まる場合、
対象コメントが折り畳まれていれば全コメントを展開し、
対象コメントにスクロールするようにした。

変更確認方法

確認1: 折り畳まれたコメントへのアンカーリンク(新規ウィンドウ)

  1. komagata でログイン
  2. hatsunoの提出物ページにアクセス(コメントが20件あるページ)
  3. ページ上部に「前のコメント( 8 / 12 )」が表示されていることを確認
  4. 「前のコメント」をクリックして全コメントを展開する
  5. 一番古いコメント(「提出物のコメント1です。」)の日時部分をクリックしてURLをコピー
  6. 新しいウィンドウ/タブでコピーしたURLを開く
  7. 期待動作: 折り畳みが自動で解除され、「提出物のコメント1です。」が表示された状態でページが開く。「前のコメント
    」ボタンは表示されない

確認2: 折り畳まれていないコメントへのアンカーリンク(デグレ確認)

  1. 同じ提出物ページで、最新コメント(「提出物のコメント20です」)の日時部分をクリックしてURLをコピー
  2. 新しいウィンドウ/タブでコピーしたURLを開く
  3. 期待動作: 該当コメントの位置にスクロールした状態でページが開く。「前のコメント」ボタンは従来通り表示される

確認3: アンカーリンクなしでのアクセス(デグレ確認)

  1. 提出物ページにアンカーリンクなし(#comment_XXX なし)でアクセス
  2. 期待動作: 従来通り最新8件のみ表示され、「前のコメント( 8 / 12 )」ボタンが表示される

確認4: 他の箇所でも同様に動作するか(任意)

Issue では日報コメント・相談でも同じ現象が報告されています。同じ comments.js
を共有しているため、コメントが9件以上ある日報や相談ページでも同様に確認できます。

Summary by CodeRabbit

  • 新機能

    • URLハッシュで指定したコメントへの直接リンクをサポート。該当の隠れたスレッドを自動で展開し、該当コメントまで確実にスクロールします。展開状況に応じて「さらに読み込む」表示を適切に切り替えます。
  • 改善

    • アンカーへのスクロール処理をより確実なタイミングで実行するよう改善しました(遅延制御の見直し)。
  • テスト

    • 折りたたまれたコメントがアンカーで正しく展開・スクロールされることを確認するシステムテストを追加しました。

ページ読み込み時にURLのハッシュが#comment_で始まる場合、
対象コメントが折り畳まれていれば全コメントを展開し、
対象コメントにスクロールするようにした。
@machida machida removed the request for review from okuramasafumi February 6, 2026 04:49
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Feb 6, 2026

Warning

Rate limit exceeded

@machida has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 15 minutes and 38 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📝 Walkthrough

Walkthrough

URLハッシュ(#comment_...)を検出すると該当アンカー以降の折りたたまれたコメントを展開し、残件数や「コメントをもっと読む」表示をクラスで切り替えた上でアンカー要素へフレーム同期(double requestAnimationFrame)でスクロールします。関連してanswer.jsの遅延スクロールがsetTimeout→rAFに置換され、システムテストが2件追加されました。

Changes

Cohort / File(s) Summary
コメント表示 / アンカー処理
app/javascript/comments.js
URLハッシュで指定されたコメントアンカーを検出した際に、該当アンカー以降の折りたたまれたスレッドコメントを展開、残件数表示と「コメントをもっと読む」コンテナの表示をCSSクラスで切替え、アンカーへdouble requestAnimationFrameでスクロールする処理をDOMContentLoaded初期化フローへ追加。
スクロール同期化
app/javascript/answer.js
300msのsetTimeoutによる遅延スクロールをdouble requestAnimationFrameによるフレーム同期スクロールへ置換。
システムテスト追加
test/system/comment/product_comments_test.rb
折りたたまれたコメントへのアンカーリンクで部分展開や全展開の挙動を検証するシステムテストを2件追加。

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • komagata
  • Miya096jp

Poem

🐇 小さなハッシュが道を示し、
折りたたみをぴょこんと解き放ち、
フレームに乗ってすっと届く、
コメントの居場所へぴょんと一跳ね、
ささやかな喜び、草むらで踊る。

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed PRのタイトルは「折り畳まれたコメントへのアンカーリンクが効くようにする」で、変更の主要な目的を明確に表現している。URLハッシュが#comment_で始まる場合に折り畳まれたコメントを展開してアンカースクロールする実装を追加するという主要な変更内容と一致している。
Description check ✅ Passed PR説明は必須セクション(Issue、概要、変更確認方法)を網羅し、詳細な動作確認手順が4つのシナリオで記載されている。ただしScreenshotセクションが欠けているため、完全ではない。
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/anchor-link-to-folded-comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@test/system/comment/product_comments_test.rb`:
- Around line 45-55: テスト product_comments_test.rb の `comments(:comment20)`
参照が存在しないためフィクスチャロードエラーが発生しています;`oldest_comment = comments(:comment20)`
を修正するには、test/fixtures/comments.yml に comment17〜comment20 を追加して `:comment20`
を定義するか、既存の折り畳まれたコメントのフィクスチャ(例: `:comment12` など)を使うようテスト内の `comments(:comment20)`
を該当の既存キーに置き換えてください(テスト名 "anchor link to folded comment unfolds and scrolls to
it" と変数 `oldest_comment` を更新)。
🧹 Nitpick comments (1)
app/javascript/comments.js (1)

45-66: アンカーリンク処理のロジックは概ね良好です。

全体的な設計は正しく、折り畳まれたコメントの展開→スクロールの流れがきちんと実装されています。いくつか細かい点を挙げます:

  1. setTimeout 300ms はやや脆弱: レンダリングに300ms以上かかった場合、スクロール先の位置が不正確になる可能性があります。requestAnimationFrame のネストや MutationObserver を使うとより堅牢になりますが、現状のユースケースでは実用上問題ない範囲だと思います。

  2. moreCommentsSection の非表示方法: Line 58 で style.display = 'none' を使っていますが、Line 39 では classList.remove('is-hidden') で表示制御しています。ただし、既存コード(Line 80)でも style.display = 'none' が使われているので、既存パターンとは一貫性があります。

ERB生成のフィクスチャキー(:comment20)の参照でエラーが
発生するため、product.comments.order(:created_at).firstで
最古のコメントを取得するように修正した。
@machida machida changed the title fix: 折り畳まれたコメントへのアンカーリンクが効くようにする [WIP] fix: 折り畳まれたコメントへのアンカーリンクが効くようにする Feb 6, 2026
全コメントを一気に展開するのではなく、アンカー対象の
コメントからそれより新しいコメントまでを表示し、
対象より古いコメントは「前のコメント」ボタンで
折り畳んだまま残すようにした。
@machida machida changed the title [WIP] fix: 折り畳まれたコメントへのアンカーリンクが効くようにする fix: 折り畳まれたコメントへのアンカーリンクが効くようにする Feb 6, 2026
固定の300ms遅延ではなくブラウザの描画サイクルに合わせて
スクロールするようにし、レンダリング時間に依存しない
堅牢な実装にした。comments.jsとanswer.jsの両方を修正。
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
app/javascript/comments.js (1)

82-86: ⚠️ Potential issue | 🟡 Minor

commentTotalCount <= initialLimit の場合、moreCommentButtonnull になり得る

Line 24 の分岐で commentTotalCount <= initialLimit の場合、「前のコメント」ボタンがDOMに存在しない可能性があります。その場合、Line 86 の addEventListenerTypeError: Cannot read properties of null が発生します。これはこのPRで導入された問題ではありませんが、Line 45-80 のアンカーロジックが先に実行される流れになったため、認識しておく価値があります。

🛡️ 修正案
  const moreCommentButton = document.querySelector(
    '.a-button.is-lg.is-text.is-block'
  )
  const moreComments = document.querySelector('.thread-comments-more')
- moreCommentButton.addEventListener('click', () => {
+ if (!moreCommentButton) return
+ moreCommentButton.addEventListener('click', () => {
🧹 Nitpick comments (2)
app/javascript/answer.js (1)

6-13: querySelector の代わりに getElementById を使用すべき

comments.js では document.getElementById(commentAnchor.slice(1)) を使用しているのに対し、ここでは document.querySelector(answerAnchor) を使用しています。querySelector はCSSセレクタとして解釈するため、IDに .: などの特殊文字が含まれる場合にエラーが発生します。getElementById の方が安全で、comments.js との一貫性も保てます。

♻️ 修正案
  if (answerAnchor) {
    requestAnimationFrame(() => {
      requestAnimationFrame(() => {
-        const anchorElement = document.querySelector(answerAnchor)
+        const anchorElement = document.getElementById(answerAnchor.slice(1))
        if (anchorElement) {
          anchorElement.scrollIntoView({ behavior: 'instant' })
        }
      })
    })
  }
app/javascript/comments.js (1)

45-80: アンカー展開ロジックは正しく実装されています。

対象コメント以降を展開し、古いコメントは折り畳んだまま残すロジックは、主要なケース(中間コメント、最古コメント、既に表示済みのコメント)を正しく処理できています。

ただし、.a-button.is-lg.is-text.is-block セレクタでのボタン取得が Line 34、Line 58、Line 82 と3箇所で重複しています。ボタン要素の取得を1箇所にまとめることを検討してください。

IDに特殊文字が含まれる場合のエラーを防ぎ、
comments.jsとの一貫性を保つ。
moreCommentButtonとmoreCommentsの取得が3箇所に
重複していたのをトップレベルで1回だけ取得するように整理した。
@machida machida self-assigned this Feb 6, 2026
@machida machida merged commit 209ff51 into main Feb 10, 2026
2 checks passed
@machida machida deleted the fix/anchor-link-to-folded-comments branch February 10, 2026 03:22
@github-actions github-actions bot mentioned this pull request Feb 10, 2026
11 tasks
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