# 機能設計書 41-useShadowRoot() / useHost()

## 概要

本ドキュメントは、Vue 3のカスタム要素（Web Components）内部からホスト要素およびShadow DOMルートにアクセスするためのComposition APIフック `useHost()` および `useShadowRoot()` の機能設計を記述する。

### 本機能の処理概要

`useHost()` と `useShadowRoot()` は、`defineCustomElement()` で定義されたVueカスタム要素のsetup()関数内から、ホスト要素（VueElement）およびそのShadow DOMルートへの参照を取得するためのフックである。

**業務上の目的・背景**：Web Components標準を用いてVueコンポーネントをカスタムHTML要素として公開する場合、コンポーネント内部からホスト要素のDOM操作やShadow DOM内のスタイル操作が必要になることがある。これらのフックは、そうしたユースケースに対して型安全かつVueのライフサイクルに統合された手段を提供する。

**機能の利用シーン**：defineCustomElement()で定義されたコンポーネント内で、ホスト要素の属性操作、Shadow DOM内へのスタイル注入、外部DOM要素との連携、ホスト要素のイベントディスパッチなど、カスタム要素固有の処理を行う場面で利用される。

**主要な処理内容**：
1. `useHost()`: 現在のコンポーネントインスタンスから`ce`プロパティ（VueElement参照）を取得して返す
2. `useShadowRoot()`: `useHost()`経由でホスト要素を取得し、その`shadowRoot`プロパティを返す
3. コンポーネントインスタンスが存在しない場合やカスタム要素でない場合は開発モードで警告を出力

**関連システム・外部連携**：Web Components API（ShadowRoot, HTMLElement）、@vue/runtime-coreの`getCurrentInstance()`

**権限による制御**：権限制御は存在しない。ただし、defineCustomElement()で定義されたコンポーネント内でのみ有効であり、通常のVueコンポーネントで呼び出した場合はnullを返す。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 画面機能マッピングに該当なし |

## 機能種別

参照取得（DOM参照アクセス）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| caller (useHost) | string | No | 呼び出し元の関数名（エラーメッセージ用） | なし |
| name (useShadowRoot) | なし | - | パラメータなし | なし |

### 入力データソース

- @vue/runtime-coreの`getCurrentInstance()`から取得されるコンポーネントインスタンス
- インスタンスの`ce`プロパティ（VueElement参照）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| useHost戻り値 | VueElement \| null | ホストのVueElementインスタンス、またはnull |
| useShadowRoot戻り値 | ShadowRoot \| null | Shadow DOMルート、またはnull |

### 出力先

呼び出し元のsetup()関数内で利用される戻り値として出力。

## 処理フロー

### 処理シーケンス

```
1. useHost() の呼び出し
   └─ getCurrentInstance() で現在のコンポーネントインスタンスを取得
2. インスタンスの存在確認
   └─ インスタンスが存在しない場合: DEVモードで警告出力 → null を返す
3. ce プロパティの取得
   └─ instance.ce (VueElement参照) を取得
4. VueElement の存在確認
   └─ ce が存在しない場合（通常コンポーネント）: DEVモードで警告出力 → null を返す
5. VueElement を返す

useShadowRoot() の場合:
1. useHost('useShadowRoot') を呼び出し
2. 取得した VueElement の shadowRoot プロパティを返す
```

### フローチャート

```mermaid
flowchart TD
    A[useHost/useShadowRoot 呼び出し] --> B[getCurrentInstance]
    B --> C{instance が存在?}
    C -->|No| D[DEV警告: active component instance なし]
    D --> E[null を返す]
    C -->|Yes| F{instance.ce が存在?}
    F -->|No| G[DEV警告: defineCustomElement以外では使用不可]
    G --> E
    F -->|Yes| H{useShadowRoot?}
    H -->|Yes| I[el.shadowRoot を返す]
    H -->|No| J[VueElement を返す]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-41-01 | カスタム要素限定 | useHost/useShadowRootはdefineCustomElementで定義されたコンポーネント内でのみ有効 | 常時 |
| BR-41-02 | setup内呼び出し | これらのフックはsetup()関数内でのみ呼び出し可能 | 常時 |
| BR-41-03 | 開発警告 | 不正な使用時にはDEVモードでのみ警告が出力される | __DEV__が有効な場合 |

### 計算ロジック

特別な計算ロジックは存在しない。

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

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

データベース操作は存在しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 警告（DEVのみ） | コンポーネントインスタンス外で呼び出した場合 | setup()内で呼び出すこと |
| - | 警告（DEVのみ） | defineCustomElement以外のコンポーネントで呼び出した場合 | defineCustomElementで定義したコンポーネント内で使用すること |

### リトライ仕様

リトライ仕様は存在しない。

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

トランザクション処理は存在しない。

## パフォーマンス要件

軽量な参照取得処理であり、特別なパフォーマンス要件はない。getCurrentInstance()の呼び出しとプロパティ参照のみで構成される。

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

- Shadow DOMの`mode: 'open'`設定により、外部からもshadowRootにアクセス可能であることに注意
- ホスト要素への直接的なDOM操作が可能になるため、XSS攻撃の入口とならないよう注意が必要

## 備考

- `useShadowRoot()` は `useHost()` のラッパー関数であり、内部で `useHost('useShadowRoot')` を呼び出す
- `shadowRoot: false` オプションでカスタム要素を定義した場合、`useShadowRoot()` は null を返す
- VueElement クラスはHTMLElementを継承しており、ブラウザ環境でない場合は空のクラスをベースとする

---

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

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

### 推奨読解順序

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

VueElementクラスとカスタム要素に関連する型定義を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | apiCustomElement.ts | `packages/runtime-dom/src/apiCustomElement.ts` | VueElementConstructor型（49-51行目）、CustomElementOptions型（53-59行目）の定義 |
| 1-2 | apiCustomElement.ts | `packages/runtime-dom/src/apiCustomElement.ts` | VueElementクラスのプロパティ定義（203-247行目）: _instance, _app, _root, _connected等 |

**読解のコツ**: VueElementクラスはHTMLElementを継承しており、Web Components標準のライフサイクル（connectedCallback, disconnectedCallback）とVueのライフサイクルを橋渡しする役割を持つ。

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

useHost()とuseShadowRoot()の実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | apiCustomElement.ts | `packages/runtime-dom/src/apiCustomElement.ts` | useHost()関数（753-771行目）: getCurrentInstance()でインスタンスを取得し、ce（カスタム要素参照）を返す |
| 2-2 | apiCustomElement.ts | `packages/runtime-dom/src/apiCustomElement.ts` | useShadowRoot()関数（777-780行目）: useHost()経由でShadow DOMルートを返す |

**主要処理フロー**:
1. **753-754行目**: getCurrentInstance()でインスタンスを取得し、instance.ceをVueElementとしてキャスト
2. **756-757行目**: elが存在すればそのまま返す
3. **758-770行目**: DEVモードでの警告処理（インスタンスなし、またはカスタム要素でない場合）
4. **777-780行目**: useShadowRoot()はuseHost()を呼び出し、el.shadowRootを返す

#### Step 3: VueElementのライフサイクルを理解する

カスタム要素のceプロパティがどのように設定されるかを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | apiCustomElement.ts | `packages/runtime-dom/src/apiCustomElement.ts` | _createVNode()メソッド（549-600行目）: vnode.ceコールバック内でinstance.ce = thisが設定される（559行目） |
| 3-2 | apiCustomElement.ts | `packages/runtime-dom/src/apiCustomElement.ts` | connectedCallback()メソッド（281-316行目）: DOM接続時の初期化処理 |
| 3-3 | apiCustomElement.ts | `packages/runtime-dom/src/apiCustomElement.ts` | _mount()メソッド（429-457行目）: アプリケーションのマウントとexposedプロパティの設定 |

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

```
useShadowRoot()
    │
    └─ useHost('useShadowRoot')
           │
           ├─ getCurrentInstance()  [@vue/runtime-core]
           │
           ├─ instance.ce → VueElement参照の取得
           │
           └─ VueElement.shadowRoot → ShadowRoot参照の返却
```

### データフロー図

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

(setup()関数内呼び出し) ──▶ getCurrentInstance()  ──▶ VueElement | null
                            │
                            ├─ instance存在確認
                            │
                            └─ instance.ce取得
                                │
                    useShadowRoot: el.shadowRoot ──▶ ShadowRoot | null
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| apiCustomElement.ts | `packages/runtime-dom/src/apiCustomElement.ts` | ソース | useHost()、useShadowRoot()、VueElementクラス、defineCustomElement()の実装 |
| index.ts | `packages/runtime-dom/src/index.ts` | ソース | useHost、useShadowRootのエクスポート |
