# ことば展開 — 日本語向けローカル定型文 Chrome 拡張

短縮文字列を日本語の定型文へ置き換える、Chrome Manifest V3 拡張の試作品です。`textarea`、文字入力用 `input`、`contenteditable` で利用できます。テンプレートと設定は `chrome.storage.local` にだけ保存し、外部通信を行いません。

詳細仕様は [SPEC.md](SPEC.md)、データの扱いと権限は [PRIVACY.md](PRIVACY.md) を参照してください。

## 公開Webデモ

`index.html` は、Chrome拡張を導入せずに同じ展開ロジック、テンプレート管理、JSON移行を試せるWebデモです。Webデモは設定をブラウザの `localStorage` に保存します。Chrome拡張本体の保存先は従来どおり `chrome.storage.local` だけです。どちらも外部通信を行いません。

公開版: https://nanotail-japanese-text-expander.pages.dev/

## 必要なもの

- 現行版 Google Chrome
- テストページを開くための Python 3 または同等のローカル HTTP サーバー
- 自動テストと ZIP 作成を行う場合は Node.js 18 以上、`zip`、`unzip`

拡張の導入と利用に npm パッケージやネット接続は不要です。

## デベロッパーモードで導入する

1. Chrome のアドレス欄へ `chrome://extensions` と入力して開きます。
2. 右上の「デベロッパー モード」を有効にします。
3. 「パッケージ化されていない拡張機能を読み込む」を押します。
4. この `README.md` と `manifest.json` がある `japanese-text-expander` フォルダーを選びます。
5. 拡張一覧に「ことば展開 — ローカル定型文」が表示され、エラーがないことを確認します。
6. Chrome のツールバーで拡張機能メニューを開き、必要なら「ことば展開」を固定します。
7. ツールバーの拡張アイコンを押し、「テンプレートを管理」から設定画面を開きます。

Chrome は通常の Web ページ上で入力を置換するため、「アクセスしたウェブサイト上にある自分の全データの読み取りと変更」相当の権限説明を表示します。実装が行う処理は、確定キーが押されたときのカーソル直前の照合と、展開成功時の文字置換だけです。

ソースを変更した後は `chrome://extensions` でこの拡張の更新ボタンを押し、確認対象ページも再読み込みしてください。

## 削除する

1. 必要なテンプレートがあれば、設定画面の「JSONをエクスポート」で保存します。
2. `chrome://extensions` を開きます。
3. 「ことば展開 — ローカル定型文」の「削除」を押します。
4. Chrome の確認画面でも削除を確定します。

拡張の削除に伴い、`chrome.storage.local` にあるテンプレートと設定も削除されます。

## テストページを開く

ターミナルでこの README があるフォルダーへ移動し、ローカルサーバーを起動します。

```bash
cd experiments/challenger/japanese-text-expander
python3 -m http.server 4173 --bind 127.0.0.1
```

Chrome で [http://127.0.0.1:4173/test-page.html](http://127.0.0.1:4173/test-page.html) を開きます。拡張を導入または更新した直後は、このページを再読み込みしてください。終了するときはターミナルで `Ctrl+C` を押します。

`file://` で直接開く方法は、Chrome 側で「ファイルの URL へのアクセスを許可する」が別途必要になるため、上記のローカルサーバーを推奨します。

## 人間による動作確認

### 初期データと3種類の入力欄

初期の確定キーは Tab です。

1. 設定画面に次の3カテゴリが1件ずつ表示されることを確認します。
   - 敬語メール
   - 問い合わせ返信
   - 日程調整
2. テストページの1行 input に `/orei` と入力し、Tab を押します。お礼文へ置き換わることを確認します。
3. textarea に `/uketsuke` と入力し、Tab を押します。問い合わせ受付文へ置き換わることを確認します。
4. contenteditable に `/nittei` と入力し、Tab を押します。日程調整文へ置き換わることを確認します。
5. パスワード欄へ `/orei` と入力して Tab を押し、展開されないことを確認します。
6. 未登録の `/unknown` で Tab を押し、文字が変わらず通常どおりフォーカスが移ることを確認します。
7. `/orei 後続` の `/orei` 直後へキャレットを置いて Tab を押し、後ろの ` 後続` を残して展開されることを確認します。
8. `/orei` の一部を選択した状態で Tab を押し、展開されないことを確認します。
9. `/orei` を日本語IMEで変換中に Tab またはEnterを押し、変換確定より先に展開されないことを確認します。
10. `/orei` の直後で Shift+Tab を押し、展開されず前の入力欄へフォーカスが移ることを確認します。

### 日時変数

1. contenteditable へ `/nittei` を展開します。
2. `{{year}}`、`{{month}}`、`{{day}}`、`{{weekday}}` が端末の当日の日付と曜日へ置き換わることを確認します。
3. 新しいテンプレートを作り、本文を `{{date}} {{time}} {{unknown}}` にします。
4. 展開すると日付が `YYYY/MM/DD`、時刻が `HH:MM` になり、未知の `{{unknown}}` は残ることを確認します。

### 登録・検索・編集・削除・確定キー

1. 短縮文字列 `/kakunin`、任意の日本語本文、説明、カテゴリを入力し、「テンプレートを追加」を押します。
2. 検索欄へ短縮文字列またはカテゴリの一部を入力し、登録したカードだけに絞り込めることを確認します。
3. カードの「編集」から本文を変更して保存し、テストページで変更後の内容が展開されることを確認します。
4. 確定キーを「Space（空白）」へ変更します。
5. テストページへ `/kakunin` と入力して Space を押し、空白を追加せず展開されることを確認します。
6. 未登録文字列で Space を押した場合は、通常どおり空白が入力されることを確認します。
7. 登録したカードの「削除」を押し、確認画面を了承した後に一覧から消えることを確認します。
8. 確定キーを Tab に戻します。

### JSON 移行と不正 JSON

1. 「JSONをエクスポート」を押し、`kotoba-tenkai-backup.json` を保存します。
2. テンプレートを1件追加または削除します。
3. 「JSONをインポート」で手順1のファイルを選び、確認画面を了承します。
4. テンプレートと確定キーがエクスポート時点へ戻ることを確認します。
5. 内容が `{` だけの `.json` ファイルを用意してインポートします。
6. エラーが表示され、現在のテンプレートが変わらないことを確認します。
7. 8 MiBを超える `.json` ファイルも、保存内容を変えずにエラーになることを確認します。

### HTML 注入を起こさないこと

1. 短縮文字列を `/html`、展開文を `<img src=x onerror=alert(1)>` として登録します。
2. テストページの contenteditable で展開します。
3. 文字列がそのまま表示され、画像や警告画面が出ないことを確認します。
4. 確認後にこのテンプレートを削除します。

## 自動テスト

このフォルダーで次を実行します。外部パッケージのインストールは不要です。

```bash
npm test
```

`textarea`、キャレットと選択範囲、文字入力用 `input`、パスワード欄、contenteditable用置換、IMEと修飾キー、日時変数、JSON移行・件数制限・不正データ拒否、Manifest権限、通信APIと危険なHTML挿入の不在を確認します。

## 配布確認用 ZIP

ソースから ZIP を作成します。

```bash
npm run build:zip
```

出力先は `dist/japanese-text-expander-v0.1.0.zip` です。ビルドはファイル時刻と格納順を固定し、同じソースから同じ ZIP を再生成できます。

ZIP の破損、余分なファイル、危険なパス、シンボリックリンク、ソースとの差分を確認します。ZIPには導入・削除手順の `README.md` とデータ取扱いの `PRIVACY.md` も含まれます。

ZIPには `SPEC.md` と `test-page.html` も含まれるため、展開先だけで仕様確認と人間による入力確認ができます。`npm test` とZIP再作成・監査は、`package.json`、`tests/`、`scripts/` があるソースツリーで実行してください。

```bash
npm run audit:zip
```

ZIP 版を導入する場合は、任意の新しいフォルダーへ ZIP を展開し、`manifest.json` が直下にあることを確認してから、そのフォルダーを「パッケージ化されていない拡張機能を読み込む」で選びます。Chrome Web Store への提出は行いません。

## 初版に含まないもの

チーム共有、クラウド同期、アカウント、決済、AI文章生成、利用状況送信、Chrome Web Storeへの提出、既存商品固有形式との互換は含みません。
