# ブックマークレット・ギャラリー（GitHub Pages 公開）Spec

**Created:** 2026-06-01
**Updated:** 2026-06-01

---

## 1. Overview

### Problem Statement
日々の作業で便利なブックマークレットを個別に作り溜めてきたが、コードがバラバラに散在しており、他人に共有したりインストールしてもらうことができない。ギャラリーとして公開する受け皿がないため、せっかくの資産が再利用されず埋もれている。

### Goal
ブックマークレット集を **GitHub Pages 上の静的ギャラリーサイト**として公開し、訪問者が「ボタンをブックマークバーへドラッグするだけ」でインストールできる状態にする。各ブックマークレットはカテゴリ別に整理され、効果・コード・利用シーンが一目で分かる。

成功の定義：
- 訪問者が説明文を読み、ドラッグ&ドロップで各ブックマークレットを導入できる
- 全ブックマークレットがカテゴリ別に閲覧でき、ソースコードをコピーできる
- GitHub Pages の URL で誰でもアクセスできる

### Non-Goals
- ブックマークレットの動的な実行サンドボックス（サイト上でその場実行するプレビュー機能）は作らない
- ユーザー認証・お気に入り保存などのバックエンド機能は持たない（完全静的サイト）
- ブラウザ拡張機能（Chrome Extension 等）としての配布はしない
- ブックマークレットの自動更新・バージョン配信機構は持たない

### Background
ブックマークレットは `javascript:` スキームの URL をブックマークに登録するだけで動作する軽量ツール。インストールに拡張機能の審査が不要で、ブラウザを問わず動く。これまでに以下の一軍メンバーが揃っており、これに新規3案を加えて公開する。

---

## 2. 受け入れ条件 (Acceptance Criteria / EARS)

> 個人開発のため、ペルソナ別ユーザーストーリーは省略。振る舞いを EARS 記法で直接定義する。

**AC-01: ドラッグ&ドロップ・インストール**
- WHEN ブックマークレットのボタンをブラウザのブックマークバーへドラッグ&ドロップする THE SYSTEM SHALL `javascript:` URL を `href` に持つアンカー要素を提供し、ブラウザがそれをブックマークとして登録できる状態にする
- IF ボタンを単純にクリックした場合 THEN THE SYSTEM SHALL ページ遷移せず、「ドラッグして登録してください」という案内を表示する（`href="javascript:..."` のクリック誤爆を防ぐ）

**AC-02: カテゴリ別閲覧**
- WHEN ページが読み込まれる THE SYSTEM SHALL 全ブックマークレットを「テキスト・編集」「ブラウジング効率化」「リサーチ」「ユーティリティ」のカテゴリ見出しの下にグルーピングして表示する
- WHEN カテゴリ見出しが表示される THE SYSTEM SHALL 各カテゴリ内に名前・効果説明・インストールボタンを並べる

**AC-03: ソースコードのコピー**
- WHEN 各ブックマークレットの「コードをコピー」ボタンを押す THE SYSTEM SHALL 該当する `javascript:` ソースをクリップボードへコピーし、コピー完了のフィードバックを表示する
- IF クリップボードAPIが利用できない環境 THEN THE SYSTEM SHALL コード全体を選択可能な `<textarea>`/`<code>` として表示する

**AC-04: X線モード（レイアウト崩れチェック）**
- WHEN X線モードのブックマークレットを実行する THE SYSTEM SHALL ページ内の全要素に1pxのアウトラインを付与する
- WHEN 同じブックマークレットを再度実行する THE SYSTEM SHALL（実装方針として）アウトラインのトグルON/OFFを切り替える（実装メモ参照）

**AC-05: ローカル確認**
- WHEN リポジトリ直下で静的サーバを起動する THE SYSTEM SHALL ビルド工程なしで `index.html` をそのまま表示できる

---

## 3. Functional Requirements

| ID | Requirement | Priority | Notes |
|----|-------------|----------|-------|
| FR-01 | 各ブックマークレットを `javascript:` URL のアンカーとして提供し、ドラッグ登録できる | P0 | AC-01 |
| FR-02 | カテゴリ別グルーピング表示 | P0 | AC-02 |
| FR-03 | ソースコードのコピー機能 | P1 | AC-03 |
| FR-04 | クリック誤爆防止（クリック時は案内表示のみ） | P1 | AC-01 |
| FR-05 | ブックマークレット定義を1つのデータファイル（`bookmarklets.js`/JSON）に集約 | P0 | データ駆動でカード自動生成 |
| FR-06 | 新規3案（QR生成 / 固定バー除去 / X線モード）の追加 | P0 | 本Specの目玉 |
| FR-06b | 拡張カタログ19種を実装（定番＋独自、合計28種を v1 収録） | P1 | 「実装候補カタログ（拡張）」参照。外部API依存を最小化 |
| FR-07 | レスポンシブ表示（PC / スマホ） | P1 | スマホ閲覧も想定 |
| FR-08 | GitHub Pages へのデプロイ（GitHub Actions or main直公開） | P0 | 公開要件 |
| FR-08b | 独自ドメインでの公開（`CNAME` 設置＋DNS設定） | P1 | ドメインは後日確定。確定までは `*.github.io` で運用 |
| FR-09 | README（日英）にサイトURL・使い方を記載 | P2 | README.md（日本語メイン）/ README.en.md（英語） |
| FR-10 | タグ／カテゴリ／キーワードでの絞り込み・検索 | P1 | 収録数増加に備え。クライアントサイド（Fuse.js/lunr.js 等）で実装。継続拡張の前提 |
| FR-11 | インストール導線の表示（デスクトップのドラッグ手順＋Firefox確認ダイアログ注記＋モバイル手順） | P1 | 共通ヘルプ or 各カード。出典の制約を反映 |
| FR-12 | 各カードに「外部依存」「難易度」等のタグバッジを表示 | P2 | `apiDependent`/`difficulty`/`tags` を可視化 |

---

## 4. Architecture

### Overview Diagram

```mermaid
graph TD
  A[訪問者ブラウザ] -->|HTTPS| B[GitHub Pages 静的ホスティング]
  B --> C[index.html]
  C --> D[styles.css]
  C --> E[app.js<br/>カード描画・コピー処理]
  E --> F[bookmarklets.js<br/>ブックマークレット定義データ]
  G[GitHub リポジトリ main] -->|GitHub Actions / Pages| B
  H[訪問者] -->|ドラッグ&ドロップ| I[ブックマークバー<br/>javascript: URL 登録]
```

### Component Responsibilities

| Component | Responsibility |
|-----------|---------------|
| `index.html` | サイトの骨格。ヘッダー、カテゴリ別カードのマウントポイント、フッター |
| `styles.css` | レイアウト・カードデザイン・レスポンシブ対応 |
| `app.js` | `bookmarklets.js` を読み込み、カテゴリ別にカードDOMを生成。コピー・クリック誤爆防止のイベント処理 |
| `bookmarklets.js` (or `.json`) | ブックマークレットの定義（id, カテゴリ, 名前, 説明, ソースコード）の単一ソース |
| GitHub Actions / Pages 設定 | main ブランチ更新時に静的サイトを公開 |

### Key Design Decisions

| Decision | Chosen | Rationale | Rejected alternatives |
|----------|--------|-----------|----------------------|
| サイト生成方式 | 素のHTML/CSS/JS（静的・ビルドレス） | ブックマークレット集という性質上、依存を最小化しGitHub Pagesに直置きできるのが最も保守しやすい | React/Vue（過剰）、静的サイトジェネレータ（ビルド工程が増える） |
| ブックマークレット定義の管理 | データ配列に集約しJSでカード生成 | 追加が1ファイルの編集で済み、HTML重複を防げる | HTMLに直書き（追加のたびに重複コピペが発生） |
| QRコード生成方式 | 外部API（api.qrserver.com）を別タブ`window.open`で叩く | 閲覧中サイトのCSPに引っかからず、ライブラリ同梱も不要 | ページ内にQRライブラリを注入（CSP違反リスク・コード肥大） |
| インストール方式 | ドラッグ&ドロップ用アンカー | ブックマークレットの標準的かつ全ブラウザ共通の導入方法 | コピペ手順のみ（UXが劣る）、拡張機能化（Non-Goal） |
| クリック誤爆対策 | `href="javascript:..."` のクリックを `preventDefault` し案内表示 | ギャラリー上で誤クリックして実行/遷移する事故を防ぐ | 対策なし（誤実行・予期せぬ挙動） |
| 継続拡張への対応 | 多軸タグ付き単一データ＋クライアントサイド検索/フィルタ | 「日々追加して発展」前提。1オブジェクト追記で増やせ、収録数が増えても探せる（既存ギャラリーの分類軸を踏襲） | 静的HTML手書き（増えると破綻）、検索なし（数十件で探せなくなる） |
| 配布UIの二段構え | 各カードに「ドラッグ用リンク」＋「コードをコピー」の両方 | Firefox 98+ のドラッグ確認ダイアログ／モバイルのドラッグ不可に両対応（出典の制約による） | ドラッグのみ（モバイル不可）、コピーのみ（PCのUXが劣る） |

---

## 5. Data Models

ブックマークレット1件を表すデータ構造。`bookmarklets.js`（または同梱JSON）に配列で保持する。

> このサイトは「日々アイデアを追加して発展させる」前提のため、1件を**多軸タグ付きの単一データ**として持ち、HTMLカードはビルド/描画時に自動生成する（追加は1ファイルの1オブジェクト追記で完結）。タグ設計は調査した既存ギャラリーの分類軸（用途別 / 実装方式別＝外部依存の有無 / 難易度）を踏襲。

```typescript
// Bookmarklet — ギャラリーに表示する1件の定義
interface Bookmarklet {
  id: string;            // 一意キー（kebab-case 例: "markdown-link-copy"）
  category: Category;    // 表示カテゴリ（主分類）
  name: string;          // 表示名（例: "Markdownリンクコピー"）
  description: string;   // 効果の説明（1〜2文）
  code: string;          // javascript: スキームを含む実行コード（ミニファイ推奨）
  tags?: string[];       // 用途タグ（検索/フィルタ用。例: ["a11y","dev","reading"]）
  apiDependent?: boolean; // 外部API/ネットワーク依存か（true ならCSPで一部サイト不可の注意表示）
  difficulty?: "易" | "中" | "難"; // 実装難易度（運用メモ）
  source?: string;       // 着想元/出典URL（任意）
  note?: string;         // 補足（対象サイト・注意点など。例: "YouTube等の動画ページで使用"）
  status?: "stable" | "beta" | "idea"; // 公開状態（idea=バックログ、未実装）
}

type Category =
  | "テキスト・編集"
  | "ブラウジング効率化"
  | "リサーチ"
  | "ユーティリティ";
```

### ブックマークレット一覧（初期搭載データ）

| id | category | name | description |
|----|----------|------|-------------|
| `markdown-link-copy` | テキスト・編集 | Markdownリンクコピー | 閲覧中ページの「タイトル」と「URL」を `[タイトル](URL)` の形でコピー |
| `char-count` | テキスト・編集 | ページの文字数カウント | ページ内の純粋な文字数（スペース除く）をポップアップ表示 |
| `design-mode-toggle` | テキスト・編集 | デザインモードON/OFF | 閲覧中のWebサイトの文字を直接書き換え・編集できるようにする |
| `playback-speed` | ブラウジング効率化 | 動画の再生速度チェンジャー | YouTube等の動画速度を任意の倍率（1.25倍/3倍など）に変更 |
| `reveal-password` | ブラウジング効率化 | パスワード覗き見 | ログイン画面などの `●●●` で隠れたパスワードを一時的に可視化 |
| `deepl-translate` | リサーチ | 選択テキストをDeepLで翻訳 | 選択テキストを保持したまま別タブでDeepL翻訳を開く |
| `open-on-mobile-qr` | ユーティリティ | 今見ているページをスマホで開く（QR） | 現在URLのQRコードを別ウィンドウで生成しスマホへ送る |
| `kill-fixed-bars` | ユーティリティ | 邪魔な固定バーを消す | スクロール追従する固定/stickyヘッダー・フッター等を非表示にする |
| `xray-outline` | ユーティリティ | 全要素レイアウト崩れチェック（X線モード） | 全要素にランダム色のアウトラインを付与し重なり・はみ出しを可視化 |

### 実装候補カタログ（拡張）

初期搭載9種に加え、今後拡充する候補。「定番（よく知られたモダン系）」と「独自・あると嬉しい」を混ぜて収録方針とする。外部APIに依存せず**ブラウザ内蔵API（SpeechSynthesis / DOM / CSS）だけで完結**するものを優先（外部依存があるものは備考に明記）。優先度 P1=次に入れたい / P2=アイデア段階。

**定番（よく知られたモダン系）**

| id | category | name | 効果 | 優先 | 実装メモ |
|----|----------|------|------|------|----------|
| `dark-mode-force` | ブラウジング効率化 | ダークモード強制 | 任意のサイトを強制的にダーク化（トグル） | P1 | `html { filter: invert(1) hue-rotate(180deg) }`＋img/video/iframeは再反転。内蔵のみ |
| `reader-mode` | ブラウジング効率化 | リーダーモード | 広告・装飾を隠し本文だけに整える | P1 | 最大の `<article>`/段落塊を残し他を非表示。内蔵のみ |
| `unlock-copy` | ブラウジング効率化 | コピー＆右クリック解除 | 選択禁止・右クリック禁止サイトを解除 | P1 | `user-select` 復活、`oncontextmenu/onselectstart/oncopy` 無効化。内蔵のみ |
| `list-images` | ユーティリティ | 全画像を一覧表示 | ページ内画像をグリッド表示しまとめてDL | P1 | `img` 収集→オーバーレイ表示。内蔵のみ |
| `extract-links` | リサーチ | 全リンク抽出 | ページ内の全 `href` を一覧テキスト化 | P2 | 内蔵のみ |
| `toggle-css` | ユーティリティ | CSS全無効化 | スタイルを切り無装飾HTMLを見る | P2 | `disabled` 切替。内蔵のみ |
| `wayback` | リサーチ | Wayback Machineで開く | 現在URLの過去版を archive.org で開く | P2 | 外部依存（web.archive.org を別タブ） |
| `read-aloud` | リサーチ | 選択テキスト読み上げ | 選択文を音声で読み上げる | P1 | `speechSynthesis`。ブラウザ内蔵TTS、外部依存なし |
| `reading-time` | テキスト・編集 | 読了時間・単語数 | 本文の文字数から読了時間を概算表示 | P2 | 内蔵のみ |

**独自・あると嬉しい**

| id | category | name | 効果 | 優先 | 実装メモ |
|----|----------|------|------|------|----------|
| `focus-reading` | ブラウジング効率化 | 集中リーディング | ビューポート中央以外を薄暗くし読書に集中 | P2 | スクロール連動オーバーレイ。内蔵のみ |
| `heading-outline` | ユーティリティ | 見出しアウトライン | `h1`〜`h6` のツリーを表示し構造を把握（X線の相棒） | P1 | SEO/構造確認。内蔵のみ |
| `flag-no-alt` | ユーティリティ | alt無し画像を赤枠 | `alt` 欠落画像を赤枠表示（a11yチェック） | P1 | X線モードと併用。内蔵のみ |
| `contrast-check` | ユーティリティ | コントラスト比チェッカ | 選択要素の文字色/背景のWCAGコントラスト比を表示 | P2 | 内蔵のみ |
| `ogp-preview` | リサーチ | OGPプレビュー | `meta og:*` を読みSNSカード風に表示 | P2 | 内蔵のみ |
| `fill-dummy` | ユーティリティ | フォーム自動入力 | name/email/tel等にダミー値を一括投入 | P2 | フォーム検証用。内蔵のみ |
| `copy-as-quote` | テキスト・編集 | 引用Markdownコピー | 選択文を `> ...` 付きでコピー | P2 | 内蔵のみ |
| `regex-highlight` | リサーチ | 正規表現ハイライト | 入力した正規表現にマッチする箇所を強調 | P2 | `prompt()`＋テキストノード走査。内蔵のみ |
| `share-scroll` | ユーティリティ | スクロール位置を共有 | 現在のスクロール位置をURLフラグメント化してコピー | P2 | 内蔵のみ |
| `page-weight` | ユーティリティ | ページ重量・DOM数 | リソース数/転送量/DOMノード数を表示 | P2 | Navigation/Resource Timing API。内蔵のみ |

> 収録方針: **v1 で全28種（初期9種＋拡張カタログ19種）を実装する**（2026-06-01 決定）。優先度欄は実装着手順の目安として残す（P1群から着手 → P2群へ）。すべて初期公開スコープに含む。

### アイデアプール（継続追加バックログ）

「日々アイデアを追加して発展させる」運用のための未実装バックログ。既存ギャラリー（出典は [References](#references)）を調査して収集。v1 後に `status: "idea"` から随時 `beta`→`stable` へ昇格させる。外部依存ありのものは CSP で一部サイトで動かないため、カードに「外部依存」タグを表示する。

| 名前 | 効果 | カテゴリ案 | 外部依存 | 難易度 | tags |
|------|------|-----------|:------:|:----:|------|
| WhatFont（フォント特定） | ホバー要素に適用中のフォント名・サイズ・行高を表示 | リサーチ | なし | 中 | dev, typography |
| Eye Dropper（色取得） | ネイティブ EyeDropper API で画面上の任意ピクセル色をHEX取得 | ユーティリティ | なし | 易 | dev, color |
| Base64 エンコード/デコード | 選択テキストをBase64で相互変換 | テキスト・編集 | なし | 易 | dev, encode |
| URIエンコード/デコード | 選択テキストをURLエンコード/デコード | テキスト・編集 | なし | 易 | dev, encode |
| UUID/ランダム値生成 | UUID・乱数を生成してコピー | ユーティリティ | なし | 易 | dev |
| ページHTMLソース表示 | 描画後DOMをHTMLソースとして別ウィンドウ表示（generated source） | リサーチ | なし | 中 | dev |
| CSSクラス一覧表示 | ドキュメント内で使用中の全CSSクラスを列挙 | リサーチ | なし | 中 | dev, css |
| SEOメタ一覧 | title/description/canonical/OGP等を一覧表示 | リサーチ | なし | 中 | seo, dev |
| テーブルをソート | ページ上の表を列クリックで昇順/降順ソート | リサーチ | なし | 中 | data |
| 全リンクをハイライト | 全ハイパーリンクを視覚的に強調 | ユーティリティ | なし | 易 | reading |
| 全画像を回転 | 全画像を指定角度で回転（崩れ確認/お遊び） | ユーティリティ | なし | 易 | fun, dev |
| 画像を全消去（軽量化） | ページ内画像を削除し表示を軽く | ブラウジング効率化 | なし | 易 | reading, perf |
| 印刷整形 | 不要要素を除去し印刷/PDF向けにクリーン表示 | ユーティリティ | なし | 中 | reading, print |
| ページをPDF化 | 印刷ダイアログ経由でPDF出力 | ユーティリティ | なし | 易 | print |
| textarea 拡大 | 小さい入力欄を大きくして編集しやすく | ブラウジング効率化 | なし | 易 | form |
| 全チェックボックスON/OFF | フォーム内チェックボックスを一括切替 | ユーティリティ | なし | 易 | form |
| 自動リロード（秒指定） | 指定秒ごとにページを自動再読込（監視用） | ユーティリティ | なし | 易 | monitor |
| 選択語をWikipedia/辞書/類語で検索 | 選択テキストを各サービスで開く | リサーチ | あり | 易 | search |
| サイト内検索（現ドメイン限定） | 現在のドメインに限定して検索 | リサーチ | あり | 易 | search |
| Google Cache / archive.is で開く | Wayback以外のアーカイブで開く（冗長化） | リサーチ | あり | 易 | archive |
| あとで読む保存（Pocket等） | 現在ページを保存サービスへ追加 | リサーチ | あり | 易 | save |
| URL短縮 | 現在URLを短縮してコピー | ユーティリティ | あり | 易 | share |
| Website Stack 判定 | 表示中サイトの技術スタックを推定表示 | リサーチ | あり | 中 | dev, seo |
| サイト稼働確認（Is it down?） | サイトのダウンを外部チェッカーで確認 | リサーチ | あり | 易 | monitor |

> 補足: 「Kill Sticky」（`fixed`/`sticky` 全除去）は既存の `kill-fixed-bars` の強化版として統合検討。「全要素アウトライン」は既存の `xray-outline` と重複のため除外済み。

### 新規3案のソースコード（FR-06）

**① 今見ているページをスマホで開く（QRコード生成）**
```javascript
javascript:(function(){
  const url = window.location.href;
  window.open('https://api.qrserver.com/v1/create-qr-code/?size=250x250&data=' + encodeURIComponent(url), '_blank', 'width=300,height=300');
})();
```

**② 画面に追従する「邪魔な固定バー」を消し去る**
```javascript
javascript:(function(){
  const elements = document.querySelectorAll('*');
  elements.forEach(el => {
    const style = window.getComputedStyle(el);
    if (style.position === 'fixed' || style.position === 'sticky') {
      el.style.display = 'none';
    }
  });
})();
```

**③ Web制作向け：全要素のレイアウト崩れチェック（X線モード）**
```javascript
javascript:(function(){
  const elements = document.querySelectorAll('*');
  elements.forEach(el => {
    const randomColor = '#' + Math.floor(Math.random()*16777215).toString(16);
    el.style.outline = `1px solid ${randomColor}`;
  });
})();
```

### DB Schema
N/A（バックエンド・データベースなし。完全静的サイト）

---

## 6. API Design

本サイト自体はAPIを提供しない。ただし一部ブックマークレットが**外部APIを利用**するため、その契約を記載する。

### 外部依存：QRコード生成API

| Method | Path | Description | Auth |
|--------|------|-------------|------|
| GET | `https://api.qrserver.com/v1/create-qr-code/` | URLをQRコード画像（PNG）に変換 | 不要 |

```
// GET https://api.qrserver.com/v1/create-qr-code/?size=250x250&data=<URLエンコード済みURL>
// Query params
//   size: string   例 "250x250"（生成画像サイズ）
//   data: string   QR化する文字列（encodeURIComponent済み）
// Response 200
//   Content-Type: image/png （QRコード画像本体）
```

> 注: このAPIは `window.open` で別タブ表示するため、閲覧中サイトのCSPの影響を受けない。

### サイト内部（クライアントのみ）
- ブックマークレット定義は `bookmarklets.js` から静的読み込み。サーバ通信なし。

---

## 7. Error Handling

| Error Case | HTTP Status | User Message | Internal Action |
|------------|-------------|--------------|-----------------|
| ブックマークレットのリンクを誤クリック | N/A | 「これはドラッグしてブックマークバーに登録してください」と案内表示 | `preventDefault()` で遷移/実行を抑止 |
| Clipboard API 非対応／権限拒否（コピー失敗） | N/A | 「コードを手動で選択してコピーしてください」 | `<textarea>` でコード全選択にフォールバック |
| QR生成APIが応答しない（QRブックマークレット） | （外部） | 別タブに空/エラー表示 | サイト側では制御不可。説明文に「外部API利用」と明記しておく |
| 固定バー除去で必要なナビまで消える | N/A | （説明文に注意書き）「ページ再読み込みで元に戻ります」 | 副作用は実行ページ依存。説明で周知 |

---

## 8. Security

- **Authentication**: なし（公開静的サイト）
- **Authorization**: なし
- **Input Validation**: ブックマークレット定義は開発者管理の静的データのみ。ユーザー入力を受け付けない
- **Sensitive Data**: 機密データの取り扱いなし。QRブックマークレットは現在URLを外部API（api.qrserver.com）に送る点を説明文で明示する
- **XSS / コード注入**: `code` フィールドはアンカーの `href` に設定するのみでサイト側で `eval` しない。`description`/`name` はテキストとして挿入し `innerHTML` への生埋め込みを避ける（`textContent` を使用）
- **外部依存の信頼性**: QR APIは第三者サービスのため、停止・仕様変更リスクを README/説明文に注記

---

## 9. Testing Strategy

| Layer | Scenarios |
|-------|-----------|
| Manual / 表示確認 | 各カテゴリのカードが正しくグルーピング表示される（AC-02） |
| Manual / インストール | 主要ブラウザ（Chrome / Firefox / Safari / Edge）でドラッグ登録 → 実行が成功する（AC-01） |
| Manual / コピー | 「コードをコピー」でクリップボードに正しいソースが入る／非対応環境でフォールバックする（AC-03） |
| Manual / 誤爆防止 | リンククリックで遷移・実行されず案内が出る（FR-04） |
| Manual / 各ブックマークレット動作 | 9種すべてを実ページ（YouTube, ログインフォーム, 記事ページ等）で実行し効果を確認 |
| Manual / レスポンシブ | スマホ幅でレイアウトが破綻しない（FR-07） |
| CI / デプロイ | main更新でGitHub Pagesが更新される（FR-08） |

> 静的サイト＋ブックマークレットという性質上、自動テストよりクロスブラウザでの手動確認が中心。必要なら `app.js` のカード生成関数だけ軽量なユニットテスト（Vitest等）を検討。

---

## 10. Implementation Notes

- **ブックマークレットのミニファイ**: `code` は1行に圧縮しておくとブックマーク登録時に扱いやすい。改行を含むと一部ブラウザで欠落するため注意。
- **IIFE で包む & 遷移防止（出典: CSS-Tricks）**: 各コードは `(()=>{ ... })()` で囲みグローバル汚染とページ既存JSとの干渉を防ぐ。値を返すコードは末尾 `void(0);` でページ遷移を防止する。
- **URLエンコード必須（出典: CSS-Tricks）**: クロスブラウザの信頼性のため、`code` 内でユーザー入力やURLを扱う箇所は `encodeURIComponent()` でエスケープ。`%` やスペースで壊れる。
- **`javascript:` のサイズ上限（出典: CSS-Tricks 実測）**: Firefox/Safari は約 65,536 バイト、Chrome は実質無制限。通常は問題ないが、大きな処理は外部スクリプト読み込みに切り出す（ただし下記CSPに注意）。
- **CSP が最大の障壁（出典: CSS-Tricks / Wikipedia CSP）**: 外部リクエストやインラインスクリプト注入は CSP で頻繁にブロックされる（GitHub/X等の堅牢なサイトで顕著）。**自己完結型（外部依存なし）を原則**とし、外部依存があるものは `apiDependent: true` を立ててカードに「外部依存・一部サイト不可」タグを表示する。
- **Firefox 98 以降のドラッグ確認ダイアログ（出典: Bugzilla #1725487）**: `javascript:` リンクをブックマークバーへドラッグすると確認ダイアログが出る仕様に変更された（複数項目混在のドラッグはブロック）。正規の登録は可能だが「ワンクリック無確認登録」はできない。→ ギャラリー側はドラッグ手順の図解と「確認ダイアログが出ます」の注記を用意する。
- **モバイルの導線（出典: How-To Geek）**: iOS/Android はドラッグ不可。先にブックマークを作成→URLを編集して `javascript:` コードを貼り付ける手順が必要。各カードの「コードをコピー」ボタン（`javascript:` 込み）はこのモバイル手順の前提でもある。
- **X線モードのトグル化（US-05改善案）**: 現状コードは付与のみ。再実行でON/OFFを切り替えるには、`<html>` に `data-xray` 属性を立て、付与済みなら全要素の `outline` を空に戻す分岐を入れる。同様に「固定バー除去」も `dataset` 退避で復元可能にできるが、初期版は実行ページ再読み込みで戻す方針で良い。
- **固定バー除去の副作用**: `position: fixed/sticky` を一律 `display:none` するため、画面によっては必要なナビゲーションも消える。説明文に「再読み込みで戻る」旨を必ず記載。
- **デザインモード**: `document.designMode = 'on'` のトグル実装が標準的。
- **DeepL連携**: `https://www.deepl.com/translator#auto/ja/<選択テキスト>` を別タブで開く形が定番。選択テキスト取得は `window.getSelection().toString()`。
- **既存ファイル**: `README.md` / `README.en.md`（リポジトリ直下）と `docs/spec.md` は0Bの空ファイルとして既に存在。READMEはサイトURLと使い方を後で埋める。
- **GitHub Pages 配置**: ルート直下に `index.html` を置き Pages のソースを `main / root` にするのが最簡。`docs/` 配信を選ぶなら Pages 設定を `main / docs` に。サイト本体の置き場所は公開前に確定する（Open Questions #1）。
- **独自ドメイン（FR-08b）**: 最終的には独自ドメインで公開する。GitHub Pages 側はリポジトリに `CNAME` ファイル（中身は対象ドメイン1行）を置き、DNS側は apex なら A/ALIAS レコードを GitHub の IP へ、サブドメインなら CNAME を `<user>.github.io` へ向ける。ドメイン確定までは `*.github.io` の既定URLで運用し、確定後に切り替える。`base href` を絶対パス前提にしないこと（独自ドメイン移行で壊れないようリンクは相対パス推奨）。

---

## 11. Open Questions

| # | Question | Owner | Due | Status |
|---|----------|-------|-----|--------|
| 1 | サイト本体の配置はリポジトリ root か `docs/` か（GitHub Pages のソース設定に直結） | akito-shoji | 2026-06-08 | Open |
| 2 | 独自ドメインを何にするか | akito-shoji | 2026-06-01 | ✅ Resolved: `bookmarklet-kit.riumu.net`（`CNAME` 設置済。DNSで `bookmarklet-kit` を `torifo.github.io` へCNAME） |
| 3 | ブックマークレット定義は `.js` 配列か外部 `.json` か | akito-shoji | 2026-06-08 | Open |
| 4 | X線モード・固定バー除去をトグル復元対応にするか（初期版スコープ） | akito-shoji | 2026-06-08 | Open |
| 5 | カテゴリ「ユーティリティ」の名称はこれで確定か（新規3案の収まり先） | akito-shoji | 2026-06-08 | Open |
| 6 | 拡張候補カタログのうち、どれを v1（初期公開）に含めるか | akito-shoji | 2026-06-01 | ✅ Resolved: 全28種を v1 に含める |

---

## References

### プロジェクト内
- `README.md`（日本語メイン）, `README.en.md`（英語）, `docs/spec.md`（本書）

### 外部API
- [QR Code Generator API (goqr.me)](https://goqr.me/api/) — `api.qrserver.com`
- [GitHub Pages ドキュメント](https://docs.github.com/pages)

### 技術リファレンス（ブックマークレットの作法・制約）
- [CSS-Tricks: A Complete Guide to Bookmarklets](https://css-tricks.com/a-complete-guide-to-bookmarklets/) — サイズ上限・エンコード・IIFE・CSP の決定版
- [Content Security Policy (Wikipedia)](https://en.wikipedia.org/wiki/Content_Security_Policy) — CSP とブックマークレットの関係
- [Bugzilla #1725487](https://bugzilla.mozilla.org/show_bug.cgi?id=1725487) — Firefox 98 のドラッグ確認ダイアログ仕様変更
- [How-To Geek: How to Use Bookmarklets on Any Device](https://www.howtogeek.com/189358/) — モバイルでの導入手順

### 参考ギャラリー・アイデア源（アイデアプールの出典）
- [Jesse Ruderman's Bookmarklets (squarefree.com)](https://www.squarefree.com/bookmarklets/) — 老舗・網羅的。Link/Form/Text/Zap/WebDev/Validation
- [marcobiedermann/awesome-bookmarklets](https://github.com/marcobiedermann/awesome-bookmarklets) — 開発者向け（a11y/Debug/Fonts/Performance/SEO）
- [ThomasOrlita/awesome-bookmarklets](https://github.com/ThomasOrlita/awesome-bookmarklets) — 実装方式で分類（データ駆動分類の手本）
- [Hongkiat: 50+ Most Useful Bookmarklets](https://www.hongkiat.com/blog/100-useful-bookmarklets-for-better-productivity-ultimate-list/) — 一般生産性向け大量リスト
- [DevelopersIO: 厳選ブックマークレット](https://dev.classmethod.jp/articles/chrome-some-bookmarklet/) — 開発実務向け（日本語）
- [MoneyForward: ブックマークレット30選](https://biz.moneyforward.com/blog/16883/) — 一般向け（日本語）
- [accessibility-bookmarklets (mreidsma)](https://mreidsma.github.io/bookmarklets/installing.html) — a11y特化・ドラッグ導入の手本
