# 機能設計書 52-XHRローダー

## 概要

本ドキュメントは、CoffeeScriptのXHRローダー機能の設計を記述する。リモートのCoffeeScriptファイルをXMLHttpRequestを使用して読み込み、ブラウザ上で実行する機能を提供する。

### 本機能の処理概要

XHRローダーは、ブラウザ環境においてリモートサーバー上にあるCoffeeScriptファイルを非同期で読み込み、コンパイルして実行するための機能である。

**業務上の目的・背景**：Webアプリケーション開発において、CoffeeScriptファイルを外部から動的に読み込む必要がある場面がある。例えば、モジュール化されたCoffeeScriptコードを遅延ロードしたり、外部のCoffeeScriptライブラリを動的に取得する場合などである。本機能は、事前にJavaScriptへのコンパイルを行わずに、ブラウザ内で直接CoffeeScriptファイルを読み込んで実行することを可能にする。

**機能の利用シーン**：
- scriptタグのsrc属性で指定されたリモートCoffeeScriptファイルの読み込み
- 動的モジュールローディング
- 外部CoffeeScriptライブラリの遅延ロード
- 開発時のホットリロード的な用途

**主要な処理内容**：
1. XMLHttpRequestオブジェクトの生成（IE対応でActiveXObjectにもフォールバック）
2. 指定URLへのGETリクエスト送信
3. レスポンステキストの取得
4. CoffeeScript.runによるコンパイルと実行
5. コールバック関数の呼び出し

**関連システム・外部連携**：
- XMLHttpRequest API
- ActiveXObject（IE互換）
- CoffeeScript.run関数

**権限による制御**：
- 同一オリジンポリシーの制約を受ける
- CORSが設定されていない外部ドメインからの読み込みは制限される

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 22 | Annotated Source - Browser | 補助画面 | load関数の解説を含む |
| 37 | Annotated Source - Browser | 補助画面 | load関数の解説を含む（v2） |

## 機能種別

データ連携 / ネットワーク処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| url | String | Yes | 読み込み対象のCoffeeScriptファイルのURL | 有効なURL形式であること |
| callback | Function | No | 読み込み完了時に呼び出されるコールバック関数 | - |
| options | Object | No | コンパイルオプション | - |
| options.sourceFiles | Array | No | ソースファイル名の配列（ソースマップ用） | - |
| hold | Boolean | No | trueの場合、即時実行せずにコールバックにパラメータを渡す | - |

### 入力データソース

- リモートサーバー上のCoffeeScriptファイル（.coffee）
- ネットワーク経由でアクセス可能なURL

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| param | Array | [responseText, options] の配列（コールバックに渡される） |
| result | Any | CoffeeScript.runによる実行結果（hold=falseの場合） |

### 出力先

- コールバック関数への引数
- ブラウザのJavaScript実行環境

## 処理フロー

### 処理シーケンス

```
1. XHRオブジェクト生成
   └─ window.ActiveXObject が存在する場合は ActiveXObject を使用
   └─ それ以外は XMLHttpRequest を使用

2. リクエスト設定
   └─ xhr.open('GET', url, true) で非同期GETリクエストを設定
   └─ xhr.overrideMimeType('text/plain') でMIMEタイプをプレーンテキストに設定

3. レスポンスハンドラ設定
   └─ xhr.onreadystatechange でステート変化を監視
   └─ readyState === 4 で完了を検知

4. ステータスチェック
   └─ status が 0 または 200 の場合は成功
   └─ それ以外の場合はエラーをスロー

5. コード実行
   └─ hold が false の場合、CoffeeScript.run を実行
   └─ コールバック関数にパラメータを渡す

6. リクエスト送信
   └─ xhr.send(null) でリクエストを送信
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{ActiveXObject存在?}
    B -->|Yes| C[ActiveXObject生成]
    B -->|No| D[XMLHttpRequest生成]
    C --> E[xhr.open GET, url, true]
    D --> E
    E --> F{overrideMimeType対応?}
    F -->|Yes| G[MIMEタイプをtext/plainに設定]
    F -->|No| H[スキップ]
    G --> I[onreadystatechangeハンドラ設定]
    H --> I
    I --> J[xhr.send null]
    J --> K{readyState === 4?}
    K -->|No| K
    K -->|Yes| L{status in 0, 200?}
    L -->|Yes| M{hold?}
    L -->|No| N[Error: Could not load URL]
    M -->|No| O[CoffeeScript.run実行]
    M -->|Yes| P[スキップ]
    O --> Q{callback存在?}
    P --> Q
    Q -->|Yes| R[callback param 呼び出し]
    Q -->|No| S[終了]
    R --> S
    N --> S
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-52-01 | IE互換対応 | ActiveXObjectが存在する場合はそちらを優先使用 | ブラウザがIEの場合 |
| BR-52-02 | ステータス0許容 | ローカルファイル読み込み時はstatus=0が正常 | file://プロトコルの場合 |
| BR-52-03 | 非同期実行 | XHRリクエストは常に非同期（async=true） | 全ケース |
| BR-52-04 | ソースファイル設定 | urlをoptions.sourceFilesに自動設定 | 全ケース |
| BR-52-05 | holdオプション | hold=trueの場合は即時実行しない | runScriptsからの呼び出し時 |

### 計算ロジック

該当なし

## データベース操作仕様

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

該当なし（ブラウザ環境のため、データベース操作は行わない）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| Error | ネットワークエラー | statusが0,200以外 | "Could not load {url}"エラーをスロー |
| SyntaxError | 構文エラー | 不正なCoffeeScriptコード | コンパイルエラーとして表示 |
| NetworkError | 接続エラー | ネットワーク接続失敗 | ブラウザのエラーハンドリングに委譲 |

### リトライ仕様

該当なし（現在の実装ではリトライ機能は提供されていない）

## トランザクション仕様

該当なし

## パフォーマンス要件

- 非同期処理のため、UIをブロックしない
- ネットワーク速度に依存
- 複数ファイルの並列読み込みは可能だが、順序保証はない

## セキュリティ考慮事項

- 同一オリジンポリシーに従う
- CORSヘッダーがない外部ドメインからの読み込みは失敗する
- HTTPSページからHTTPリソースの読み込みは混合コンテンツとしてブロックされる可能性
- 信頼できないソースからのコード読み込みには注意が必要

## 備考

- status=0はローカルファイル（file://プロトコル）読み込み時に返される
- overrideMimeTypeはCoffeeScriptファイルが正しいMIMEタイプで配信されない場合の対策

---

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

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

### 推奨読解順序

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

XHRローダーは主にURL文字列とオプションオブジェクトを扱う。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | browser.coffee | `src/browser.coffee` | options構造体とコールバックの形式 |

**読解のコツ**: paramは `[responseText, options]` の配列形式でコールバックに渡される。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | browser.coffee | `src/browser.coffee` | load関数の実装（40-56行目） |

**主要処理フロー**:
1. **40行目**: load関数の定義 - url, callback, options, holdの4パラメータ
2. **41行目**: options.sourceFilesにURLを設定
3. **42-45行目**: XHRオブジェクト生成（ActiveXObject/XMLHttpRequest）
4. **46行目**: GETリクエストの設定
5. **47行目**: MIMEタイプのオーバーライド
6. **48-55行目**: onreadystatechangeハンドラの設定
7. **56行目**: リクエスト送信

#### Step 3: レスポンス処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | browser.coffee | `src/browser.coffee` | onreadystatechangeハンドラ内の処理（48-55行目） |

**主要処理フロー**:
- **49行目**: readyState === 4 のチェック
- **50行目**: status in [0, 200] の成功判定
- **51行目**: paramの構築 `[xhr.responseText, options]`
- **52行目**: hold=false時のCoffeeScript.run実行
- **54行目**: エラー時のException throw
- **55行目**: コールバック呼び出し

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

```
CoffeeScript.load(url, callback, options, hold)
    │
    ├─ XMLHttpRequest / ActiveXObject
    │      │
    │      ├─ open('GET', url, true)
    │      │
    │      ├─ overrideMimeType('text/plain')
    │      │
    │      └─ send(null)
    │
    └─ onreadystatechange
           │
           ├─ status check (0 or 200)
           │      │
           │      ├─ [success] CoffeeScript.run(param...) [if !hold]
           │      │
           │      └─ [error] throw Error
           │
           └─ callback(param) [if callback exists]
```

### データフロー図

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

URL             ───▶  XMLHttpRequest.GET  ───▶  responseText
                              │
options         ───▶         │
                              ▼
                      CoffeeScript.run()
                              │
                              ▼
                      JavaScript実行結果
                              │
callback        ◀───  [responseText, options]
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| browser.coffee | `src/browser.coffee` | ソース | load関数の実装 |
| coffeescript.coffee | `src/coffeescript.coffee` | ソース | compile関数（runから呼び出し） |
