noteの壁、壊しました。音声ユーザーが自作したChrome拡張

埋め込みを入れる。
音声を入れる。
画像を入れる。

noteで記事を書くとき、この3つの操作にいつも詰まっていた。

カーソルを合わせられない。入口にたどり着けない。
頑張ればできる、ではない。そもそも到達できない。

だから、Chrome拡張を自作した。


以前、こんな記事を書きました。

音声だけで操作すると、noteにもこんな壁がある!共同マガジン脱退をVoiceOverでやってみる

これは何とか操作は自力でできました。

しかし、今回はどうがんばっても無理でした。


😤 noteのエディターでつまずいた

今回つまずいたのは、noteのWeb版エディターです。

ショートカットも試しました。でも、時間がかかる以前に、そもそも挿入ポイントにカーソルを合わせられないことがありました。

特につらいのが、埋め込み・音声・画像。記事の体験を作る大事な部分ほど、そこで詰まる。

たとえばYouTubeの埋め込み。

「+ボタンを探す → メニューを開く → 埋め込みを選ぶ → URLを入力」

ボタンにはたどり着ける。でも、意図した位置に挿入できない。極端な話、最初か最後にしか入れられない。

ここで詰まるだけで、制作のスピードも気持ちも削られます。


💡 発想を変えた

公式エディターを作り変えるのではなく、公式エディターの上に、薄い補助レイヤを足す。

そのために作ったのが、自作Chrome拡張の Note Editor Helper です。

狙ったのは、派手な機能ではありません。

いまカーソルがある位置。そこを起点に、必要な挿入を最短で通す。

埋め込み、音声、画像。私が一番困っていた「挿入」を助けることだけに集中しました。

この拡張を使うと:
「Alt+↓で段落移動 → Alt+Iで挿入位置を設定 → +ボタンから埋め込み」
意図した位置に、確実に挿入できる。


🛠️ 拡張の特徴

この拡張でできることは、シンプルです。

ショートカットキー一覧:

| キー | 動作 |
|------|------|
| Alt + T | 目次を開く(見出し一覧にジャンプ) |
| Alt + ↑ | 前のブロックへ移動 |
| Alt + ↓ | 次のブロックへ移動 |
| Alt + I | 現在位置を挿入ポイントに設定 |
| Alt + / | ヘルプを表示 |

音声読み上げ対応:

  • 移動するたびに「3/10 見出し: 発想を変えた」のように現在位置を読み上げ

  • 目次を開くと、見出しだけを一覧表示

  • 操作結果をすべて音声で通知

noteのエディターは ProseMirror というリッチテキストエディタを使っています。この拡張は、その上に「キーボードだけで段落を移動できる層」を追加しています。


🤖 コーディングAIに作らせた

今回使ったのは、コーディングに特化したAI。いわゆる「バイブコーディング」という手法です。

バイブコーディングについては、以前の記事で詳しく書いています。

コードが書けなくても大丈夫。AIと4行プロンプトで作る「点字学習ゲーム」

バイブコーディングとは、コードを自分で書かずに、AIに「こういうものが欲しい」と伝えて作らせる方法。プログラミングの知識がなくても、困りごとと理想を言葉にできれば、動くものが手に入る。

コードが書けなくても、検証とフィードバックができれば、自分専用のツールが作れる時代です。


📝 AIに渡した要件定義

以下が、実際にコーディングAIに渡したプロンプトです。このままコピーして渡せば、同じ拡張が作れます。

【1. 概要】
note.com のエディター(editor.note.com および note.com)で動作するChrome拡張を作成してください。
目的は、スクリーンリーダー(音声読み上げソフト)を使うユーザーが、キーボードだけでエディター内を移動し、任意の位置に挿入ポイントを設定できるようにすることです。

【2. 対象環境】
- Chrome拡張(Manifest V3)
- 動作サイト: editor.note.com/* および note.com/*
- noteのエディターは ProseMirror を使用しています

【3. 機能要件】

3-1. ブロック移動機能
- Alt + ↓: 次のブロック(段落、見出し、区切り線、画像など)へ移動
- Alt + ↑: 前のブロックへ移動
- 移動時、現在位置を「3/10 見出し: タイトル名」のように読み上げ
- 最初または最後のブロックに達したら、その旨を読み上げ

3-2. 目次機能
- Alt + T: 見出し(h2)の一覧をダイアログで表示
- ↑↓キーで選択、Enterで該当見出しへ移動
- Iキーで選択中の見出しの後に挿入位置を設定
- Escでダイアログを閉じる
- 選択中の見出しを読み上げ

3-3. 挿入位置設定機能
- Alt + I: 現在のブロックの末尾を挿入ポイントとして設定
- 設定後、「挿入位置を設定: ○○ の後」と読み上げ
- ProseMirrorがカーソル位置を認識できるよう、マウスイベントのシミュレートを行う

3-4. ヘルプ機能
- Alt + /: ショートカットキー一覧をalertで表示

【4. アクセシビリティ要件】
- すべての操作結果を aria-live="assertive" で読み上げ
- ダイアログには role="dialog" と aria-label を設定
- リストボックスには role="listbox" と aria-selected を設定
- フォーカス管理を適切に行い、ダイアログを閉じたらエディターにフォーカスを戻す

【5. セキュリティ要件】
- 外部サーバーへの通信は一切行わない
- ユーザーの入力内容や記事データを収集・送信しない
- localStorage や cookies へのアクセスは行わない
- DOM操作は note.com ドメイン内のみに限定(manifest.jsonのmatchesで制限)
- Content Security Policy を遵守
- eval() や new Function() は使用しない
- innerHTMLへのユーザー入力の代入は行わない(XSS対策)
- 外部ライブラリは読み込まない(依存関係を持たない)

【6. ファイル構成】
- manifest.json: 拡張の設定ファイル
- content.js: メインの処理(キーボードイベント、DOM操作、読み上げ)
- styles.css: 読み上げ用要素の非表示スタイル

【7. manifest.json の要件】
- manifest_version: 3
- content_scripts で note.com と editor.note.com にマッチ
- permissions は最小限(特別な権限は不要)
- アイコンは48pxと128pxを用意

【8. 実装上の注意】
- ProseMirrorエディターは .ProseMirror クラスで取得
- ブロック要素は h2, p, hr, figure をセレクタで取得
- カーソル移動は Selection API と Range API を使用
- ProseMirrorにカーソル位置を認識させるため、mousedown/mouseup イベントをシミュレート
- 目次ダイアログが開いているときは、他のショートカットを無効化

📦 拡張の構成ファイル

Chrome拡張は3つのファイルで構成されます。

| ファイル | 役割 |
|----------|------|
| manifest.json | 拡張の名前、バージョン、動作するサイト、読み込むファイルを指定 |
| content.js | キーボード操作を受け取り、エディター内を移動する処理 |
| styles.css | 読み上げ用の非表示要素のスタイル |

これらを同じフォルダに入れて、Chromeに読み込ませます。


📥 Chromeにインポートする方法

この拡張はChrome Web Storeに公開していません。「デベロッパーモード」で手動インストールします。

手順:

  1. 3つのファイルを同じフォルダに入れる

  2. Chromeで `chrome://extensions` を開く

  3. 画面右上の「デベロッパーモード」をオンにする

  4. 「パッケージ化されていない拡張機能を読み込む」をクリック

  5. ファイルが入ったフォルダを選択

  6. 完了。noteのエディターを開くと自動で有効になる

注意:

  • デスクトップ版Chrome限定です

  • Chromeを更新すると、まれに拡張が無効になることがあります(再度有効化すればOK)


🎁 配布について

もし同じ悩みがあって、試してみたい方がいれば、拡張ファイルの提供も考えています。コメントで意思表示をいただければ、受け渡し方法を案内します。

※デスクトップ版Chrome限定。環境差で動かない場合もあります。動作保証はできませんが、同じ壁にぶつかっている方の助けになれば。


#アクセシビリティ #視覚障害 #Chrome拡張 #note #全盲クリエイター #AI活用 #バイブコーディング

いいなと思ったら応援しよう!