# 画面設計書 31-ファイル表示

## 概要

本ドキュメントは、GitLabのリポジトリ内の個別ファイル内容を表示する画面（ファイル表示画面）の設計を記述したものである。

### 本画面の処理概要

本画面は、リポジトリ内の特定ファイルの内容を閲覧するための画面である。ソースコード、テキストファイル、画像、PDFなど様々な形式のファイルを適切なビューアで表示し、開発者がコードレビューやファイル確認を効率的に行えるようにする。

**業務上の目的・背景**：開発プロジェクトにおいて、リポジトリ内のファイル内容を確認することは最も基本的かつ頻繁に行われる操作である。本画面は、ファイル内容の表示に加え、シンタックスハイライト、行番号表示、ファイルメタデータ表示などの機能を提供し、コードの理解と品質向上を支援する。また、ファイル編集、Blame表示、履歴確認など関連機能へのナビゲーションのハブとしても機能する。

**画面へのアクセス方法**：
- ファイルツリー画面からファイル名をクリック
- URL直接入力: `/{namespace}/{project}/-/blob/{ref}/{path}`
- 検索結果からのリンク
- コミット詳細画面からのファイルリンク

**主要な操作・処理内容**：
1. ファイル内容の表示（シンタックスハイライト付き）
2. 行番号の表示とパーマリンク生成
3. Raw形式でのファイルダウンロード
4. ファイル編集画面への遷移
5. Blame表示画面への遷移
6. コミット履歴の確認
7. Web IDEでの編集
8. ファイルのコピー（パス、内容）

**画面遷移**：
- 遷移元: ファイルツリー画面、検索結果画面、コミット詳細画面、マージリクエスト詳細画面
- 遷移先: ファイル編集画面、Blame表示画面、コミット一覧画面、Web IDE、Raw表示

**権限による表示制御**：
- リポジトリ読み取り権限がない場合はアクセス拒否
- 編集権限がない場合は編集ボタンが非表示
- フォークして編集するオプションが権限に応じて表示

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 15 | ファイル閲覧 | 主機能 | ファイル内容の表示 |
| 23 | Blame表示 | 補助機能 | Blame表示への遷移 |
| 16 | ファイル編集 | 遷移先機能 | ファイル編集画面への遷移 |
| 21 | コミット閲覧 | 補助機能 | 最終コミット情報の表示 |
| 141 | Web IDE | 遷移先機能 | Web IDEでの編集 |

## 画面種別

詳細

## URL/ルーティング

```
GET /{namespace}/{project}/-/blob/{ref}/{*path}
```

**ルート定義**: `config/routes/repository.rb`
```ruby
scope path: '/blob/*id', as: :blob do
  get '/', action: :show
end
```

## 入出力項目

| 項目名 | 入出力 | 型 | 必須 | 説明 |
|--------|--------|-----|------|------|
| namespace | 入力 | String | Yes | プロジェクトの名前空間 |
| project | 入力 | String | Yes | プロジェクト名 |
| ref | 入力 | String | Yes | ブランチ名/タグ名/コミットSHA |
| path | 入力 | String | Yes | ファイルパス |
| ref_type | 入力 | String | No | 参照タイプ（heads/tags） |

## 表示項目

| 項目名 | 説明 | データソース |
|--------|------|-------------|
| ファイルパス（パンくずリスト） | ファイルの階層パス | @blob.path |
| ファイル名 | 表示中のファイル名 | @blob.name |
| ファイルサイズ | ファイルのバイトサイズ | @blob.raw_size |
| 行数 | テキストファイルの行数 | @blob.lines |
| 最終コミット情報 | 最後の変更コミット | @last_commit |
| ブランチ/タグ名 | 現在の参照 | @ref |
| ファイル内容 | シンタックスハイライト付き内容 | @blob.data |
| MIMEタイプ | ファイルの種類 | @blob.mime_type |
| パーマリンク | コミットSHA付きURL | commit.id + @path |

## イベント仕様

### 1-ファイル内容表示

ページロード時にファイル内容を取得し表示する。

**処理フロー**:
1. URLからref、pathを抽出
2. リポジトリからblobオブジェクトを取得
3. ファイル種別に応じたビューアを選択
4. シンタックスハイライト処理を適用
5. 行番号付きで内容を表示

### 2-Raw表示ボタン押下

ファイルの生データをダウンロードまたは表示する。

**遷移先**: `/{namespace}/{project}/-/raw/{ref}/{path}`

### 3-編集ボタン押下

ファイル編集画面へ遷移する。

**遷移先**: `/{namespace}/{project}/-/edit/{ref}/{path}`

**前提条件**: 編集権限を持つこと

### 4-Blameボタン押下

Blame表示画面へ遷移する。

**遷移先**: `/{namespace}/{project}/-/blame/{ref}/{path}`

### 5-履歴ボタン押下

ファイルのコミット履歴画面へ遷移する。

**遷移先**: `/{namespace}/{project}/-/commits/{ref}/{path}`

### 6-Web IDEで開くボタン押下

Web IDEでファイルを開く。

**遷移先**: `/-/ide/project/{namespace}/{project}/edit/{ref}/-/{path}`

### 7-行番号クリック

特定行へのパーマリンクを生成・コピーする。

**処理**: URLに`#L{行番号}`を付加

## データベース更新仕様

### 操作別データベース影響一覧

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| ファイル表示 | - | SELECT | データベース更新なし（Gitリポジトリから直接読み取り） |

本画面は参照専用であり、データベースへの書き込みは発生しない。ファイル内容はGitリポジトリから直接読み取られる。

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 発生条件 |
|-------------|------|---------------|----------|
| M001 | エラー | "File exceeds 10MB and can't be edited in the browser. Edit locally and push your changes." | 編集しようとしたファイルが10MB超 |
| M002 | エラー | "Blame for binary files is not supported." | バイナリファイルでBlame表示しようとした |
| M003 | 警告 | "This is a large file. Showing a limited preview." | 大きなファイルの部分表示 |
| M004 | 情報 | "This file is stored with Git LFS." | LFSファイルの場合 |

## 例外処理

| 例外 | 発生条件 | 処理内容 |
|------|---------|---------|
| 404 Not Found | ファイルが存在しない | 404エラーページ表示 |
| 403 Forbidden | 読み取り権限なし | アクセス拒否画面表示 |
| ディレクトリの場合 | パスがディレクトリを指す | ファイルツリー画面へリダイレクト |
| バイナリファイル | テキスト以外のファイル | 適切なビューアで表示またはダウンロードリンク |

## 備考

- ファイルサイズが大きい場合（1MB以上）、部分的に表示される
- バイナリファイル（画像、PDF等）は専用ビューアで表示
- LFSで管理されたファイルはLFSポインタではなく実際の内容を表示
- Monaco Editorがプリロードされ、Web IDE起動が高速化される

---

## コードリーディングガイド

本画面を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

まず、Blobオブジェクトの構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | blob.rb | `app/models/blob.rb` | Blobモデルの基本構造、ビューア選択ロジック |
| 1-2 | repository.rb | `app/models/repository.rb` | リポジトリからのblob取得メソッド |

**読解のコツ**: GitLabでは、Blobは単なるデータコンテナではなく、表示ロジック（ビューア選択）も含む。`simple_viewer`と`rich_viewer`の概念を理解すること。

#### Step 2: エントリーポイントを理解する

処理の起点となるコントローラーを特定。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | blob_controller.rb | `app/controllers/projects/blob_controller.rb` | showアクション、before_action群 |

**主要処理フロー**:
1. **71行目**: `def show` - メインのアクション定義
2. **24-38行目**: `before_action` - 認証・認可チェック
3. **72行目**: `conditionally_expand_blob` - Blob内容の展開
4. **74-84行目**: `respond_to` - HTML/JSONレスポンス分岐
5. **299-310行目**: `show_html` - HTML表示用のデータ準備

#### Step 3: ビューテンプレートを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | show.html.haml | `app/views/projects/blob/show.html.haml` | メインテンプレート構造 |
| 3-2 | _blob.html.haml | `app/views/projects/blob/_blob.html.haml` | Blob表示パーシャル |
| 3-3 | _header.html.haml | `app/views/projects/blob/_header.html.haml` | ファイルヘッダー（アクションボタン群） |

**主要処理フロー**:
- **7行目**: GraphQLクエリの登録（blob_info）
- **15-22行目**: ファイルブラウザの条件分岐表示
- **19行目**: `render 'blob'`で実際の内容表示

#### Step 4: ビューア（Viewer）システムを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | base.rb | `app/models/blob_viewer/base.rb` | ビューアの基底クラス |
| 4-2 | rich/ | `app/models/blob_viewer/rich/` | リッチビューア群（Markdown、画像等） |
| 4-3 | simple/ | `app/models/blob_viewer/simple/` | シンプルビューア群（テキスト） |

### プログラム呼び出し階層図

```
Projects::BlobController#show
    │
    ├─ ExtractsPath#assign_ref_vars
    │      └─ ExtractsRef#extract_ref_without_atom
    │
    ├─ blob (memoized)
    │      └─ @repository.blob_at(commit.id, @path)
    │             └─ Gitlab::Git::Blob.find
    │
    ├─ conditionally_expand_blob
    │      └─ blob.load_all_data!
    │
    └─ show_html
           ├─ Environments::EnvironmentsByDeploymentsFinder
           ├─ @repository.last_commit_for_path
           └─ Gitlab::CodeNavigationPath
```

### データフロー図

```
[入力]               [処理]                    [出力]

URL Parameters ───▶ BlobController#show ───▶ HTML/JSON Response
  - namespace         │
  - project           ├─▶ Repository.blob_at ───▶ Blob Object
  - ref               │      │
  - path              │      └─▶ Git Repository
                      │
                      ├─▶ Viewer Selection ───▶ Appropriate Viewer
                      │
                      └─▶ Last Commit Info ───▶ Commit Metadata
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| blob_controller.rb | `app/controllers/projects/blob_controller.rb` | コントローラー | リクエスト処理 |
| show.html.haml | `app/views/projects/blob/show.html.haml` | テンプレート | メインビュー |
| _blob.html.haml | `app/views/projects/blob/_blob.html.haml` | パーシャル | Blob表示 |
| _header.html.haml | `app/views/projects/blob/_header.html.haml` | パーシャル | ヘッダー表示 |
| blob.rb | `app/models/blob.rb` | モデル | Blobオブジェクト |
| repository.rb | `app/models/repository.rb` | モデル | リポジトリ操作 |
| extracts_path.rb | `app/controllers/concerns/extracts_path.rb` | Concern | パス抽出 |
| repository.rb | `config/routes/repository.rb` | ルーティング | URL定義 |
| blob_info.query.graphql | `app/graphql/queries/repository/blob_info.query.graphql` | GraphQL | データ取得クエリ |
