# 画面設計書 4-カスタムスクリプトタグデモ

## 概要

本ドキュメントは、babel-standaloneパッケージに含まれる「カスタムスクリプトタグデモ」画面の設計仕様を定義する。この画面は `Babel.disableScriptTags()` と `Babel.transformScriptTags()` を使用した手動変換制御機能を実演するためのデモページである。

### 本画面の処理概要

この画面では、通常のDOMContentLoaded時の自動変換を無効化し、JavaScriptコードで動的にscript要素を生成した後、任意のタイミングで明示的に `Babel.transformScriptTags()` を呼び出して変換を実行する。これにより、開発者がBabel変換のタイミングを完全に制御できることを実演する。

**業務上の目的・背景**：この画面は、Babel standaloneの自動変換機能をより細かく制御したいケースでの使用方法を示すために提供されている。例えば、動的にスクリプトを追加する場合や、特定の条件を満たした後に変換を実行したい場合など、自動変換では対応できないシナリオに対応する。SPAやダイナミックコンテンツを扱うアプリケーションでの利用を想定している。

**画面へのアクセス方法**：ローカルサーバーまたはファイルシステムから直接 `packages/babel-standalone/examples/scriptTag-custom.htm` にアクセスする。ブラウザでHTMLファイルを開くことで画面が表示される。

**主要な操作・処理内容**：
1. ページ読み込み時にbabel.jsライブラリが読み込まれる
2. インラインスクリプトで `Babel.disableScriptTags()` が呼び出され、自動変換が無効化される
3. JavaScriptで動的にscript要素が生成され、`type="text/babel"` と `text` プロパティが設定される
4. 生成されたscript要素が `<head>` に追加される
5. `Babel.transformScriptTags()` が明示的に呼び出され、変換と実行が行われる
6. 実行結果として"Hello world"メッセージとBabelバージョンが画面に表示される

**画面遷移**：本画面は独立したデモページであり、他の画面への遷移機能は存在しない。ユーザーは直接URLを指定してアクセスする。

**権限による表示制御**：認証・認可機能は実装されておらず、すべてのユーザーが同一の機能を利用できる。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 14 | @babel/standalone | 主機能 | disableScriptTags/transformScriptTagsによる手動変換制御 |
| 1 | @babel/core | API連携 | transformScriptTags経由でBabel.transformを呼び出しコード変換 |
| 16 | @babel/preset-react | 補助機能 | デフォルトプリセットとしてJSX構文をサポート |
| 15 | @babel/preset-env | 補助機能 | デフォルトプリセットとしてES2015+構文を変換 |

## 画面種別

デモ / 手動変換制御サンプル

## URL/ルーティング

ファイルパス: `packages/babel-standalone/examples/scriptTag-custom.htm`

※ローカルファイルとして直接開くか、Webサーバー経由でアクセスする

## 入出力項目

| 項目名 | 項目ID | 入力/出力 | データ型 | 必須 | 説明 |
|--------|--------|----------|----------|------|------|
| 結果表示エリア | output | 出力 | string | - | 変換・実行後のメッセージを表示するpre要素 |
| Babelバージョン | version | 出力 | string | - | 使用中のBabelバージョンを表示するstrong要素 |

## 表示項目

| 項目名 | 表示形式 | 説明 |
|--------|----------|------|
| Using Babel ラベル | テキスト | バージョン表示のラベル |
| Babelバージョン | strong要素内テキスト | Babel.versionの値 |
| 結果表示 | pre要素内テキスト | 初期表示は"Loading..."、実行後は"Hello world" |

## イベント仕様

### 1-ページ読み込みと自動変換無効化

1. babel.jsスクリプトが読み込まれ、グローバルBabelオブジェクトが初期化される
2. インラインスクリプト（type="text/javascript"）が即座に実行される
3. `Babel.disableScriptTags()` が呼び出される
4. DOMContentLoadedイベントリスナーが削除され、自動変換が無効化される

### 2-動的スクリプト要素の生成

1. `document.createElement('script')` で新しいscript要素が作成される
2. `script.type = 'text/babel'` で変換対象として設定される
3. `script.text` にES2015+コード（アロー関数、テンプレートリテラル）が設定される
4. `document.querySelector('head').appendChild(script)` でDOMに追加される

### 3-手動変換の実行

1. `Babel.transformScriptTags()` が明示的に呼び出される
2. `runScripts(transform, scriptTags)` が実行される
3. ページ内の `type="text/babel"` scriptタグが検出される
4. 動的に追加されたスクリプトの内容が変換される
5. 変換後のコードが新しいscript要素として `<head>` に追加・実行される

### 4-スクリプト実行（doStuff関数）

1. 変換後のスクリプト内の `doStuff()` 関数が呼び出される
2. `name` 変数に 'world' が代入される
3. テンプレートリテラルを使用して `Hello ${name}` 文字列が生成される
4. `#output` 要素のinnerHTMLに "Hello world" が設定される
5. `#version` 要素のinnerHTMLに Babel.version が設定される

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

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

本画面はフロントエンドのみで動作するデモ画面であり、データベースへのアクセスは発生しない。

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| - | - | - | データベース操作なし |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| MSG001 | 初期表示 | Loading... | ページ読み込み直後、手動変換実行前 |
| MSG002 | 成功 | Hello world | スクリプト変換・実行成功後 |
| MSG003 | 警告（コンソール） | You are using the in-browser Babel transformer... | transformScriptTags呼び出し時（開発警告） |

## 例外処理

| 例外ケース | 対応 | ユーザーへの表示 |
|-----------|------|-----------------|
| babel.js読み込み失敗 | ブラウザエラー | Babelオブジェクトが未定義となり、disableScriptTags/transformScriptTagsが呼び出せない |
| 動的スクリプト追加失敗 | DOM操作エラー | コンソールにエラーが出力される |
| 構文エラー | Babel変換時エラー | コンソールにエラーが出力される |
| DOM要素が見つからない | JavaScript実行時エラー | コンソールにエラーが出力される |

## 備考

- 本画面は開発者向けのデモンストレーション目的であり、本番環境での利用は推奨されていない
- `Babel.disableScriptTags()` は `window.removeEventListener("DOMContentLoaded", ...)` を呼び出す
- 動的に追加されたscript要素も、transformScriptTags呼び出し時に変換対象となる
- 複数回 `transformScriptTags()` を呼び出した場合、未実行のスクリプトのみが対象となる
- script要素の `text` プロパティを使用してコードを設定している

---

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

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

### 推奨読解順序

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

手動変換制御で使用されるAPIの構造を理解することが重要である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | index.ts | `packages/babel-standalone/src/index.ts` | disableScriptTags関数の実装（283-285行目） |
| 1-2 | index.ts | `packages/babel-standalone/src/index.ts` | transformScriptTags関数の実装（274-278行目） |

**読解のコツ**: `disableScriptTags` は単純にイベントリスナーを削除するだけ。`transformScriptTags` は引数としてscriptタグコレクションを受け取ることができる。

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

HTMLファイル内のスクリプト構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | scriptTag-custom.htm | `packages/babel-standalone/examples/scriptTag-custom.htm` | HTML構造と動的スクリプト生成ロジック（1-30行目） |

**主要処理フロー**:
1. **11行目（HTML）**: babel.jsスクリプトの読み込み
2. **14行目**: `Babel.disableScriptTags()` で自動変換を無効化
3. **16-23行目**: script要素を動的に生成してheadに追加
4. **27行目**: `Babel.transformScriptTags()` で明示的に変換実行

#### Step 3: 自動変換無効化の仕組みを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | index.ts | `packages/babel-standalone/src/index.ts` | onDOMContentLoaded関数（260-262行目） |
| 3-2 | index.ts | `packages/babel-standalone/src/index.ts` | DOMContentLoadedイベントリスナー登録（266-268行目） |
| 3-3 | index.ts | `packages/babel-standalone/src/index.ts` | disableScriptTags関数（283-285行目） |

**主要処理フロー**:
- **266-268行目**: `window.addEventListener("DOMContentLoaded", onDOMContentLoaded, false)` でリスナー登録
- **283-285行目**: `window.removeEventListener("DOMContentLoaded", onDOMContentLoaded)` でリスナー削除

#### Step 4: 手動変換実行の処理フローを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | index.ts | `packages/babel-standalone/src/index.ts` | transformScriptTags関数（274-278行目） |
| 4-2 | transformScriptTags.ts | `packages/babel-standalone/src/transformScriptTags.ts` | runScripts関数（240-270行目） |
| 4-3 | transformScriptTags.ts | `packages/babel-standalone/src/transformScriptTags.ts` | loadScripts関数のインラインスクリプト処理（226-230行目） |

**主要処理フロー**:
- **274-278行目（index.ts）**: `transformScriptTags` が `runScripts(transform, scriptTags)` を呼び出す
- **244-246行目（transformScriptTags.ts）**: 引数がない場合、全scriptタグを取得
- **228-229行目**: インラインスクリプトの場合、`script.innerHTML` から内容を取得

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

```
ブラウザ
    │
    ├─ <script src="../babel.js">  ... babel-standaloneライブラリ読み込み
    │      │
    │      └─ window.addEventListener("DOMContentLoaded", ...)  ... 自動変換登録
    │
    └─ <script type="text/javascript">  ... 同期実行
           │
           ├─ Babel.disableScriptTags()  ... index.ts:283
           │      │
           │      └─ window.removeEventListener("DOMContentLoaded", ...)  ... 自動変換無効化
           │
           ├─ document.createElement('script')  ... 動的要素生成
           │      │
           │      ├─ script.type = 'text/babel'
           │      │
           │      └─ script.text = "ES2015+コード"
           │
           ├─ head.appendChild(script)  ... DOM追加
           │
           └─ Babel.transformScriptTags()  ... index.ts:274
                  │
                  └─ runScripts(transform, undefined)  ... transformScriptTags.ts:240
                         │
                         ├─ document.getElementsByTagName("script")  ... 全scriptタグ取得
                         │
                         └─ loadScripts(transformFn, jsxScripts)  ... :173
                                │
                                ├─ script.innerHTML から内容取得  ... :228-229
                                │
                                └─ run(transformFn, result)  ... :105
                                       │
                                       ├─ transformCode()
                                       │
                                       └─ headEl.appendChild(scriptEl)
                                              │
                                              └─ doStuff() 実行
```

### データフロー図

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

Babel.disableScriptTags()   ──▶    イベントリスナー削除          ──▶   自動変換無効化
                                                                         │
document.createElement()    ──▶    script要素生成                ──▶   DOM追加
    │                                    │                              │
    │ type="text/babel"                  │ script.text設定              │
    │ text="ES2015+コード"               │                              ▼
    │                                    │                         <head>に追加
    └────────────────────────────────▶  │                              │
                                         │                              │
Babel.transformScriptTags() ──▶    runScripts()                  ──▶   変換実行
                                         │                              │
                                         │ loadScripts()                ▼
                                         │   └─ transformCode()    新規script追加
                                         │       └─ Babel.transform()    │
                                         │                              │
                                         └──────────────────────────────┤
                                                                         ▼
                                                               #output: "Hello world"
                                                               #version: Babel.version
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| scriptTag-custom.htm | `packages/babel-standalone/examples/scriptTag-custom.htm` | テンプレート | デモ画面のHTML構造、手動変換制御ロジック |
| babel.js | `packages/babel-standalone/babel.js` | ライブラリ | ビルド済みBabel standaloneライブラリ |
| index.ts | `packages/babel-standalone/src/index.ts` | ソース | disableScriptTags/transformScriptTags関数の実装 |
| transformScriptTags.ts | `packages/babel-standalone/src/transformScriptTags.ts` | ソース | scriptタグ検出・変換・実行のコア処理 |
