Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
WYSIWYG ルビ入力の概要と Chromium のバグを修正した話
Search
kosakin
June 22, 2026
Technology
270
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
WYSIWYG ルビ入力の概要と Chromium のバグを修正した話
#rich_text_editor_study
https://web-study.connpass.com/event/391357/
kosakin
June 22, 2026
More Decks by kosakin
See All by kosakin
pタグを跨いだテキストコピーは 改行が2つになる!?
karintou8710
0
39
RTE ライブラリの仕組みとそれを支えるブラウザ機能
karintou8710
0
650
Sample
karintou8710
0
310
Other Decks in Technology
See All in Technology
攻撃と防御で学ぶAI時代のプロダクトセキュリティ演習
recruitengineers
PRO
9
2.8k
その“隠したつもり”が命取り ── 自前と平文をやめて「正解」に委ねる
kuroneko13
0
120
事業価値と Engineering 2026年度版
recruitengineers
PRO
49
24k
[ChatGPT Work LT]事務作業が苦手な人のための バックオフィスの「半」自動化
chimaki_iot
0
290
Goでデータパイプラインを作ろう
sansantech
PRO
1
450
ラジオの科学
frievea
0
320
私がブラウザを自作したくなった理由
supurazako
1
230
Bill One 開発エンジニア 紹介資料
sansan33
PRO
7
19k
つくって納得、つかって実感! 大規模言語モデルことはじめ ver2.0
recruitengineers
PRO
4
1.6k
Head First モブプログラミング / Head First Mobprogramming
takaking22
10
12k
PLATEAU で バーチャル花火大会
tatsuya1970
0
160
【Google Cloud Next Tokyo'26】Gemini Enterprise と Oracle AI Database で実現する、業務データ活用を実現する AI エージェント実装
shisyu_gaku
0
250
Featured
See All Featured
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.8k
Designing for Performance
lara
611
70k
Context Engineering - Making Every Token Count
addyosmani
9
1.1k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
287
14k
Leveraging Curiosity to Care for An Aging Population
cassininazir
1
470
Ten Tips & Tricks for a 🌱 transition
stuffmc
0
170
Statistics for Hackers
jakevdp
799
230k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
46
2.9k
Redefining SEO in the New Era of Traffic Generation
szymonslowik
1
380
Designing Powerful Visuals for Engaging Learning
tmiket
1
490
Google's AI Overviews - The New Search
badams
0
1.1k
16th Malabo Montpellier Forum Presentation
akademiya2063
PRO
0
350
Transcript
WYSIWYG ルビ入力の概要と Chromium のバグを修正した話 2026.05.26 (火) #rich_text_editor_study 1
所属:サイボウズ株式会社 (26卒) 出身:札幌 最近の興味:家系・ポーカー 悩み:健康診断の結果が悪かったので、娯楽の 食事が奪われた 2 自己紹介 コサキン @karintou74073
• 文字にふりがなや補足情報を付ける仕組み • 日本では漫画・小説・教科書・新聞などで広く使用 • 難読漢字や固有名詞の読みを示し、読者の理解を助ける • 縦書きと併用されることが多い ルビとは何か 3
• 中国: 拼音(ピンイン)で発音を示す例あり • ただし漢字と発音がほぼ 1:1 対応のため、主に教育用途 専門家が少なく、開発者コミュニティでも優先度が低い • WYSIWYG
ライブラリでも「知識がないので利用者側で対応してほしい」という反応 • 例: Lexical / Tiptap の issue でも実装は後回し 他の国でのルビ 4 Web やライブラリでの実装は後回しにされがち
ルビの HTML 表現 5 • ruby タグの中にテキスト + rt タグを順に並べる
• rp タグはルビ非対応環境向けのフォールバック • 「明日(Ashita)」のようにカッコ付きで表示
静的ページは HTML を直接書けばよいが、CMS などでユーザー入力を受ける場合は入力方法が必要 Web でのルビ入力 3 パターン 6
• マークダウンで専用記法を用意 • note の例: |note太郎《ノートたろう》→ プレビュー時に変換 パターン 1: マークダウン記法
7 • note は本来 WYSIWYG ベースのエディタ • それでも記法を採用 = WYSIWYG の難しさ / Web の技術的制約がある?と推測 • 記法はサービスごとに様々なバリエーションが存在
• ルビを独立した要素 (アトム) として扱う / 入力はモーダルなどの専用画面から行う パターン 2: アトム +
専用入力画面 8 • 「単語 + ルビ」は 1 つの埋め込み要素として扱われる • キャレットで直接文字を編集することはできない • ネイティブアプリの Word がこの方式
• contenteditable を使った、純粋な WYSIWYG(一番直感的に思いつく形) 編集イメージ • 単語にもルビにもキャレットを合わせて編集できる • 矢印キーで単語とルビの間を移動できる •
「やさしい日本語エディタ WordPress プラグイン」など パターン 3: 単語とルビを直接編集 9
• ルビが増えてくると、純粋に読みづらい • WYSIWYG なのに、最終成果物と異なる表示で編集することになる 「パターン 1: マークダウン記法」の問題点 10
現状では実用的ではない • キャレット操作が十分に実装されていない • 致命的な変な挙動も大量にある(ここら辺誰も触ってなさそう) • ブラウザ依存の実装になっている • editing の内部動作は
W3C の仕様が存在しない • ルビ + contenteditable 周りは WPT (共通テスト) にもない 「パターン3:単語とルビを直接編集」の問題点 11 https://codesandbox.io/p/sandbox/zxrrw8 Chrome で起きる変な動作 (contenteditable=true) - ルビの右にキャレット → 左矢印で行頭に移動 - そのまま Backspace すると行頭までごっそり削除 - ルビの先頭で入力 → 単語の末尾に追加される - 通常テキストで縦移動 → ルビに吸い込まれて抜け出せない - `rt` タグが空だと、ルビを入力できない
• Chrome で縦方向に移動すると、なぜか文頭や文末に飛ぶ • ProseMirror は移動処理を基本ブラウザに委ねているため、ライブラリでも問題が起きる WYSIWYG だと、アトムルビで十分では? 12 「アトム
+ 専用入力画面」で十分だと考える理由 • ルビは表示領域が小さく、直接入力しづらい • 多くの変な動作を乗り越えてまで直接編集する価値はそこまで高くない アトムルビの問題点
©️ Cybozu, Inc. 13 ここまでは記事の内容
©️ Cybozu, Inc. 14 社内の方がリツイートしてくれたおかげで、Chromium 開発者の方に届いた
とりあえず ISSUE 立てるか 15
• IssueTracker というサービスに報告する • 再現方法や詳細、バージョンなどを入力する。他の OSS とあまり変わらない Chromium に ISSUE
報告をする 16
数日経っても誰も取り組んでなさそう。。 17
ブラウザへのコントリビュート 興味あるし、やるか! 18
©️ Cybozu, Inc. 1. まずは手元に Clone して、ビルドする(僕の環境だと7時間ぐらいかかった気がする) 2. 原因の調査 3.
main からブランチを切って、コード修正とテストコードを追加する 4. Gerrit というサービスに PR を送る(若干特殊) 5. レビューでやり取り後、権限を持つ2人に Approve をもらってマージしてもらう コントリビュートの流れ 19 • Jxck さんの「Chromium にコントリビュートするための周辺知識」を目がとれるほど読みました • 日本語でコントリビュートガイドがあることに感謝です • https://blog.jxck.io/entries/2024-03-26/chromium-contribution.html
©️ Cybozu, Inc. 20 PRのイメージ
©️ Cybozu, Inc. • Blink は Chromium のレンダリングエンジン • HTML
/ CSS の解析、レイアウト構築、描画や Web API の実装を担っている • Firefox は Gecko, Safari は WebKit • 今回関わるのは layout と editing の2つ • third_party/blink/renderer/core/editing/ • third_party/blink/renderer/core/layout/ 変更するコンポーネント:Blink 21
©️ Cybozu, Inc. • Claude Code にディレクトリ構造・ファイル内容を聞きながら、理解を深めていく • ある程度バグありそうな場所を見つけたら、伝家の宝刀 print
デバッグ • LOG(ERROR) << "Foo"; 簡単な原因説明 • ArrowDown を押すと、レイアウト層で「次行 and 横方向ピクセルが一番近い位置」に移動したい • レイアウトは DOM を描画するための構造に変換されたもの • <rt /> は内部的に行と同じタイプで管理されており、これを次行と誤認 • contenteditable=false の中に移動しようとして、フォールバックが起動して末尾に移動 原因の調査方法 22
©️ Cybozu, Inc. • PR をレビューしていただいた田村さんにおんぶに抱っこだった • 最初に提案した contenteditable=false に移動する場合にスキップする方法は、contenteditable=true
でも同 じ問題が起きているため却下 • 別案で、レイアウトの層で <rt /> ならスキップする処理にしたい • IsRubyAnnotationLine の判定用メソッドを別PRで追加していただき、私がそれを使うという流れを提案して いただいた。(神??) レビューでの会話 23
©️ Cybozu, Inc. 24 マージされて AUTHORS にのった!嬉しい!
• アトムルビの WYSIWYG 編集が主要ブラウザである程度まともに動くようになる! • 別のバグっぽいものを見つけているので、その修正も必要になるかも。。。 • 主要ブラウザで詳しくバグ調査をせねば。。。 • 今主流のマークダウン形式が、WYSIWYG
の選択肢が生まれる! • Web で実用的な縦書きエディタを実装する上の、第一歩でもある • Web で縦書きエディターを各々のサービス導入できる世界線、いいね この修正で何が嬉しい? 25
©️ Cybozu, Inc. • 今はマークダウン記法でルビを入力していることが多いが見づらく、WYSIWYG の選択肢が欲しい • contenteditable=false のルビバグを修正したので、PC の主要ブラウザは動きそう
• 他にもバグあるのかも(あった記憶がある) • editing はブラウザへのコントリビュートしたい方の一つの選択肢になる! • 縦書き周りでレイアウト・editing 周りのバグっぽいものはいくつか見つけた • Web でルビが普及していけばいいね! まとめ 26
©️ Cybozu, Inc. 27