# 画面設計書 5-スクリプト無効化デモ

## 概要

本ドキュメントは、babel-standaloneパッケージに含まれる「スクリプト無効化デモ」画面の設計仕様を定義する。この画面は `Babel.disableScriptTags()` を使用して `text/babel` スクリプトの自動変換を完全に無効化する機能を実演するためのデモページである。

### 本画面の処理概要

この画面では、`Babel.disableScriptTags()` を呼び出すことで、ページ内に存在する `type="text/babel"` のscriptタグが変換・実行されないことを実演する。これにより、特定のスクリプトの実行を意図的に防止できることを示す。セキュリティ上の観点や、条件付き実行制御のユースケースに対応する機能である。

**業務上の目的・背景**：この画面は、Babel standaloneの自動変換機能を完全に無効化したいケースでの使用方法を示すために提供されている。例えば、ユーザー入力に基づいてスクリプトの実行可否を判断したい場合や、セキュリティ要件により動的スクリプト実行を防止したい場合などに利用される。CSP（Content Security Policy）との組み合わせや、サンドボックス環境での利用を想定している。

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

**主要な操作・処理内容**：
1. ページ読み込み時にbabel.jsライブラリが読み込まれる
2. 即座に `Babel.disableScriptTags()` が呼び出され、自動変換が無効化される
3. `type="text/babel"` のscriptタグがページ内に存在するが、変換・実行されない
4. pre要素には初期テキスト "This line should not be overwritten!" が維持される
5. スクリプト内の `doStuff()` 関数は呼び出されない

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

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

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 14 | @babel/standalone | 主機能 | Babel.disableScriptTagsでtext/babelスクリプトの自動変換を無効化 |

## 画面種別

デモ / セキュリティ・制御機能サンプル

## URL/ルーティング

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

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

## 入出力項目

| 項目名 | 項目ID | 入力/出力 | データ型 | 必須 | 説明 |
|--------|--------|----------|----------|------|------|
| 結果表示エリア | output | 出力 | string | - | 初期テキストが維持されることを確認するpre要素 |

## 表示項目

| 項目名 | 表示形式 | 説明 |
|--------|----------|------|
| 結果表示 | pre要素内テキスト | 初期テキスト "This line should not be overwritten!" が維持される |

## イベント仕様

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

1. babel.jsスクリプトが読み込まれ、グローバルBabelオブジェクトが初期化される
2. Babel standaloneの初期化処理でDOMContentLoadedイベントリスナーが登録される
3. 即座に次のscriptタグが実行される
4. `Babel.disableScriptTags()` が呼び出される
5. `window.removeEventListener("DOMContentLoaded", onDOMContentLoaded)` が実行される
6. DOMContentLoadedイベントリスナーが削除され、自動変換が無効化される

### 2-text/babelスクリプトの非実行

1. DOMContentLoadedイベントが発火する
2. しかし、イベントリスナーは削除済みのため `transformScriptTags()` は呼び出されない
3. `type="text/babel"` のscriptタグは変換・実行されない
4. スクリプト内の `doStuff()` 関数は呼び出されない
5. `#output` 要素のテキストは初期値のまま維持される

### 3-期待される画面状態

1. pre要素に "This line should not be overwritten!" が表示されたまま維持される
2. "I did an evil operation!" は表示されない
3. コンソールには特にエラーや警告は出力されない

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

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

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

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

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| MSG001 | 表示維持 | This line should not be overwritten! | 自動変換が無効化され、スクリプトが実行されない場合（正常動作） |
| MSG002 | 異常表示 | I did an evil operation! | 自動変換が有効な場合（disableScriptTagsが効いていない場合） |

## 例外処理

| 例外ケース | 対応 | ユーザーへの表示 |
|-----------|------|-----------------|
| babel.js読み込み失敗 | ブラウザエラー | Babelオブジェクトが未定義となり、disableScriptTagsが呼び出せない |
| disableScriptTags呼び出し失敗 | JavaScript実行時エラー | text/babelスクリプトが実行され、"I did an evil operation!" が表示される |

## 備考

- 本画面は開発者向けのデモンストレーション目的であり、本番環境での利用は推奨されていない
- `Babel.disableScriptTags()` はDOMContentLoadedイベント発火前に呼び出す必要がある
- text/babelスクリプト内のコードは「悪意のある操作」を模したダミーテキストを使用している
- このデモでは「スクリプトが実行されないこと」が成功状態である
- 複数のtext/babelスクリプトがある場合、すべてが無効化される
- 一度無効化した後に `transformScriptTags()` を呼び出せば、明示的に変換・実行することは可能

---

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

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

### 推奨読解順序

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

自動変換の無効化に関連するイベントリスナー管理を理解することが重要である。

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

**読解のコツ**: `onDOMContentLoaded` という名前付き関数をリスナーとして登録することで、後から `removeEventListener` で削除できるようになっている。

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

HTMLファイルのスクリプト実行順序を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | scriptTag-disabled.htm | `packages/babel-standalone/examples/scriptTag-disabled.htm` | HTML構造と無効化ロジック（1-19行目） |

**主要処理フロー**:
1. **8行目（HTML）**: pre要素に初期テキスト "This line should not be overwritten!" を設定
2. **10行目**: babel.jsスクリプトの読み込み
3. **11行目**: `Babel.disableScriptTags()` を即座に呼び出し
4. **12-17行目**: `type="text/babel"` スクリプトが存在するが、変換されない

#### Step 3: 無効化の仕組みを詳細に理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | index.ts | `packages/babel-standalone/src/index.ts` | disableScriptTags関数（283-285行目） |
| 3-2 | index.ts | `packages/babel-standalone/src/index.ts` | transformScriptTags関数（274-278行目）- 呼び出されない |

**主要処理フロー**:
- **266-268行目**: babel.js読み込み時に `window.addEventListener("DOMContentLoaded", onDOMContentLoaded, false)` が実行される
- **11行目（HTML）**: `Babel.disableScriptTags()` が呼び出される
- **284行目（index.ts）**: `window.removeEventListener("DOMContentLoaded", onDOMContentLoaded)` が実行される
- DOMContentLoaded発火時、リスナーは存在しないため何も実行されない

#### Step 4: 実行されないスクリプトの内容を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | scriptTag-disabled.htm | `packages/babel-standalone/examples/scriptTag-disabled.htm` | type="text/babel"スクリプト（12-17行目） |

**非実行コードの内容**:
- **13-15行目**: `doStuff()` 関数の定義（アロー関数）
- **14行目**: `#output` 要素のinnerHTMLを "I did an evil operation!" に変更しようとする
- **16行目**: `doStuff()` の呼び出し
- これらのコードはすべて実行されない

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

```
ブラウザ
    │
    ├─ HTML解析開始
    │      │
    │      └─ <pre id="output">This line should not be overwritten!</pre>  ... 初期テキスト設定
    │
    ├─ <script src="../babel.js">  ... babel-standaloneライブラリ読み込み
    │      │
    │      └─ index.ts モジュール初期化
    │             │
    │             └─ window.addEventListener("DOMContentLoaded", onDOMContentLoaded, false)
    │                    ... 自動変換イベントリスナー登録
    │
    ├─ <script>Babel.disableScriptTags()</script>  ... 同期実行
    │      │
    │      └─ disableScriptTags()  ... index.ts:283
    │             │
    │             └─ window.removeEventListener("DOMContentLoaded", onDOMContentLoaded)
    │                    ... イベントリスナー削除
    │
    ├─ <script type="text/babel">...</script>  ... 変換対象スクリプト（DOMに追加のみ）
    │      │
    │      └─ 【実行されない】
    │
    └─ DOMContentLoaded イベント発火
           │
           └─ 【リスナーなし - transformScriptTags()は呼び出されない】
```

### データフロー図

```
[入力/状態]                     [処理]                          [出力/結果]

babel.js読み込み           ──▶  addEventListener()          ──▶  リスナー登録済み
                                     │
                                     ▼
Babel.disableScriptTags()  ──▶  removeEventListener()       ──▶  リスナー削除済み
                                     │
                                     ▼
<script type="text/babel"> ──▶  【変換処理なし】            ──▶  DOM要素として存在のみ
    │                                │
    │ doStuff() 定義                 │
    │ (実行されない)                 │
    │                                │
    └────────────────────────────▶  │
                                     │
DOMContentLoaded発火       ──▶  【リスナーなし】            ──▶  何も起きない
                                     │
                                     ▼
#output要素               ────────────────────────────────▶  "This line should not be overwritten!"
    │                                                           （初期値維持）
    │ 変更されない
    │
    └─ "I did an evil operation!" は表示されない
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| scriptTag-disabled.htm | `packages/babel-standalone/examples/scriptTag-disabled.htm` | テンプレート | デモ画面のHTML構造、無効化デモロジック |
| babel.js | `packages/babel-standalone/babel.js` | ライブラリ | ビルド済みBabel standaloneライブラリ |
| index.ts | `packages/babel-standalone/src/index.ts` | ソース | disableScriptTags関数の実装、イベントリスナー管理 |
| transformScriptTags.ts | `packages/babel-standalone/src/transformScriptTags.ts` | ソース | scriptタグ検出・変換・実行のコア処理（本画面では呼び出されない） |
