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
What We Talk About When We Talk About Editor
Search
Masafumi Oyamada
August 18, 2012
Programming
2.6k
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
What We Talk About When We Talk About Editor
ブラウザ内のエディタ事情
Masafumi Oyamada
August 18, 2012
More Decks by Masafumi Oyamada
See All by Masafumi Oyamada
大規模言語モデルを作る、拡張する
stillpedant
48
16k
Other Decks in Programming
See All in Programming
壊れたパーサから始める関数型設計と構成的なパーサ #fp_matsuri
raiga0310
2
440
AIが無かった頃の素敵な出会いの話
codmoninc
1
360
「人を評価する AI」の設計と実装
ryoyanara
0
120
TSX の <Hoge<Fuga>> という構文に驚いた話 / tsx-type-argument-syntax
kanaru0928
0
200
複数の Claude Code が"放置"されてしまう問題をCLI ダッシュボードを自作して解決した話
sumihiro3
1
640
AWS CDK を「作」ってみた 〜フルスクラッチで見えた CDK の裏側〜 / aws-cdk-from-scratch
gotok365
3
2.8k
コーディングルールの鮮度を保ちたい for SRE NEXT 2026 / keep-fresh-go-internal-conventions-sre-next-2026
handlename
0
170
使いながら育てる Claude Code — 開発フローの1コマンド化 × 繰り返し指摘の自動仕組み化
shiki_kakaku
0
1.6k
使用 Meilisearch 建立新聞搜尋工具
johnroyer
0
210
『コードを書く以外の』エンジニアリング〜課金基盤移行プロジェクト推進のためのTips4選
yuriko1211
0
560
PHP初心者セッション2026 〜生成AIでは見えない裏側を知る:今だからLAMPを通して仕組みを学ぶ〜
kashioka
0
800
Claude Team Plan導入・ガイド
tk3fftk
0
250
Featured
See All Featured
The AI Search Optimization Roadmap by Aleyda Solis
aleyda
1
6k
The Mindset for Success: Future Career Progression
greggifford
PRO
0
430
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
34
2.8k
Art, The Web, and Tiny UX
lynnandtonic
304
22k
Making the Leap to Tech Lead
cromwellryan
135
10k
Writing Fast Ruby
sferik
630
63k
From π to Pie charts
rasagy
0
240
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
254
22k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
62k
A Modern Web Designer's Workflow
chriscoyier
698
190k
技術選定の審美眼(2025年版) / Understanding the Spiral of Technologies 2025 edition
twada
PRO
119
120k
Digital Ethics as a Driver of Design Innovation
axbom
PRO
1
360
Transcript
ブラウザ内のエディタ事情 1 id: mooz / @stillpedant
id:mooz / @stillpedant ┃アドオン開発 KeySnail: Firefox を Emacs ライクに
Clipple: クリップボード拡張 gpum: Gmail 用のポップアップ・インタフェース ┃Firefox Hacks Rebooted KeySnail について ECMAScript5 について ┃See also http://mooz.github.com/index-ja.html 2
発表の内訳 エディタ 80% 拡張機能 20% 3
発表の流れ 1. <textarea> における高度な編集機能 どのように高度な編集機能が実装されるかを解説 2. 独自エディタ ブラウザ内エディタを分類しその実装を解説
3. source-editor.jsm Firefox 11 より利用可能となった source-editor.jsm に ついて概説 4
5 <textarea> における高度な編集機能
<textarea> ┃最も馴染み深いブラウザ内エディタ: <textarea> ブログの更新 Web メーラー ┃編集機能は貧弱
基本的なカーソルの移動操作 カット,ペースト,アンドゥ ┃高度な編集機能が欲しい 文字列の置換機能 スニペット機能 矩形編集機能 6 どうやって独自の編集機能を実現する?
独自の編集機能に必要なもの ┃基本的な操作 エディタ内のテキストを取得 カーソル位置の取得と設定 選択範囲の取得と設定 テキストの編集
挿入: insert(start, text) 削除: delete(start, end) ┃高度な編集機能 上記の操作を組み合わせて実装可能 7 基本的な操作はどう実現する?
テキストの取得 ┃テキストの取得 var textArea = document.querySelector(“#editor”); var wholeText
= textArea.value; ┃テキストの設定 textArea.value = “abc”; 注意点 テキストを設定するとテキストエリアのスクロール位置が先頭 へとリセットされる 設定前にスクロール位置 (scrollTop) を保存し,設定後にスク ロールし直す必要がある 8 var savedScrollTop = textArea.scrollTop; textArea.value = someText; textArea.scrollTop = savedScrollTop;
カーソル位置の操作 ┃カーソル位置 テキストの先頭からみたカーソルのオフセット 改行文字もカウントされる ┃カーソル位置の取得 ┃カーソル位置の設定 9 function
setCaret(textArea, caret) { textArea.setSelectionRange(caret, caret); } function getCaret(textArea) { return textArea.selectionStart; } abcd 3
選択範囲の取得と設定 ┃選択範囲の取得 textArea.selectionStart textArea.selectionEnd ┃選択範囲の設定 textArea.setSelectionRange(start, end)
HTML5 では setSelectionRange(start, end, “backward”) などとできる 10 forward backward
テキストの編集: 単純な方法 ┃単純な方法 編集後のテキストを文字列操作で生成 生成したテキストを textArea.value に代入 11
function insert(start, insertText) { var originalText = textArea.value; textArea.value = originalText.substring(0, start) + insertText + originalText.substring(start); } function delete(start, end) { var originalText = textArea.value; textArea.value = originalText.substring(0, start) + insertText + originalText.substring(0, end); } 手作業で 編集後の文字列を 計算してあげる 手作業で 編集後の文字列を 計算してあげる
テキストの編集: 賢い方法 ┃賢い方法 textArea の TextNode を直接操作 ┃利点
まどろっこしい文字列操作がいらない JS レベルでの操作が少ないため高速?(未検証) 12 function insert(start, text) { var textNode = textArea.firstChild; textNode.insertData(start, text); } function delete(start, end) { var textNode = textArea.firstChild; textNode.replaceData(start, end - start, „‟); } firstChild
高度な編集機能の実現 ┃基本的な操作がそろった エディタ内のテキストを取得 カーソル位置の取得と設定 選択範囲の取得と設定 テキストの編集
┃基本的な操作を組み合わせて置換機能を実現 textArea.value.indexOf() などで置換対象文字列を検索 置換対象文字を選択してハイライト delete(replacee), insert(replacer) して置換を実行 (textNode.replaceData を使えば一発) 13 基本的な操作さえあれば高度な機能が実現できる
コーヒーブレイク ┃Emacs http://www.gnu.org/software/emacs/ 14 http://cpplover.blogspot.jp/2012/08/vim-vs-emacs.html
コーヒーブレイク ┃Ymacs http://www.ymacs.org/ ブラウザ上に Emacs を再現 15
16 独自エディタ
さまざまなブラウザ内エディタ ┃Ymacs http://www.ymacs.org/ ┃CodeMirror 2 http://codemirror.net/ jsdo.it
も利用 ┃ACE Editor http://ace.ajax.org/ ┃Skywriter (Bespin) [Ace Editor へ移行] https://mozillalabs.com/en-US/skywriter/ ┃Eclipse Orion http://www.eclipse.org/orion/ Firefox の Scratch Pad も利用 17 構文の強調表示など <textarea> では実現できないことを 実現するために頑張っている
独自エディタの分類 ┃1. キーイベント全解釈タイプ Ymacs ┃2. contentEditable タイプ Eclipse
Orion CodeMirror 1 多くの WYSIWYG エディタ Evernote, Gmail, Tumblr, … ┃3. hidden textarea タイプ CodeMirror 2 ACE Editor 18 ブラウザの用意した 入力機構を使うタイプ 独自の入力機構を使うタイプ
1. キーイベント全解釈タイプ ┃方針 イベントリスナを使って全てのキーイベントを監視 イベントを順に解釈することでビューを構築 ┃例 入力イベント列:
a, b, <backspace>, c, <left>, d 生成されるビュー: a d c 19 Ymacs カーソル Ymacs ユーザ イベントリスナ キー入力 入力が不可能なビュー (<div>,<span>, …) イベントを解釈し ビューを構築
キーイベント全解釈タイプの利点・欠点 ┃利点 自由度高 ┃欠点 マルチバイト文字の入力が実現し難い IME がからむとキーイベントがまともに飛ばない
Ymacs もマルチバイト文字の入力は未サポート コンテキストメニューからの編集ができない ビューが入力可能要素ではない キーイベントが飛ばない 20 Ymacs ユーザ イベントリスナ キー入力 入力が不可能なビュー (<div>,<span>, …) イベントを解釈し ビューを構築
2. contentEditable タイプ ┃方針 ビュー要素に contentEditable 属性を設定し入力可能に ビューの構築は基本的にブラウザ任せ
一部のキー入力のみを独自に解釈 ショートカットキーの実現 21 Eclipse Orion CodeMirror 1 ユーザ キー入力 contentEditable で入力可能なビュー (<div>,<span>, …)
contentEditable タイプの利点・欠点 ┃利点 入力関係の問題が生じにくい(マルチバイト文字) コンテキストメニューからの編集も問題ない ┃欠点 ブラウザにより
contentEditable 系の挙動が異なる 差異を吸収するために多くのコードを書く必要がある CodeMirror はこれにこりて 2 で contentEditable から脱却 エディタ要素を iframe 内に仕込む必要がある 初期化が同期的ではなく,これによる問題が多々発生 22 Eclipse Orion CodeMirror 1 ユーザ キー入力 contentEditable で入力可能なビュー (<div>,<span>, …)
3. hidden textarea タイプ ┃方針 hidden な textarea を用意してユーザの入力を受け付け
textarea にフォーカスしておく textarea の内容からビューを構築 23 CodeMirror2 ACE Editor Ymacs ユーザ hidden な textarea キー入力 入力が不可能なビュー (<div>,<span>, …) textarea の中身を見て ビューを構築
hidden textarea タイプの利点・欠点 ┃利点 ブラウザ間の挙動の違いに悩まされなくて良い ┃欠点 実装が大変
http://codemirror.net/doc/internals.html コンテキストメニューからの操作がほぼ効かない 「全選択」など 24 Ymacs ユーザ hidden な textarea キー入力 入力が不可能なビュー (<div>,<span>, …) textarea の中身を見て ビューを構築 CodeMirror2 ACE Editor
さまざまなエディタ実装 ┃高度な編集機能の実現 エディタ実装毎にコードを書く必要がある 大変 きりがない ┃どうにかならないか
統一的なインタフェースがあると良い 25
26 source-editor.jsm
source-editor.jsm ┃resource:///modules/source-editor.jsm Firefox 11 より(公式に)利用可能に アドオン内でソースコードエディタを実現 ┃様々なバックエンド
SourceEditor は単なるエディタインタフェース ビューを含む実際の挙動はバックエンド次第 デフォルトのバックエンド: Eclipse Orion contentEditable タイプ 27 SourceEditor Orion アドオン YYY ZZZ
source-editor.jsm の使い方 ┃エディタの挿入場所の用意 (placeholder) ┃SourceEditor の初期化 28 <vbox id="editor" flex="1"/>
var placeholder = document.getElementById("editor"); var config = { mode: SourceEditor.MODES.JAVASCRIPT, showLineNumbers: true }; var editor = new SourceEditor(); editor.init(placeholder, config, function onInitialize() { // 初期化後の処理 });
何が嬉しいか ┃SourceEditor に対する高度な編集機能 SourceEditor の用意する基本操作を組み合わせて実現 いちど実装してしまえば様々なバックエンドで動作 エディタに対する統一的なインタフェース
┃SourceEditor の利用により もう↓のようなことにならなくて済む 29 ┃高度な編集機能の実現 エディタ実装毎にコードを書く必要がある 大変 きりがない
30 まとめ
まとめ 31 ┃<textarea> における高度な編集機能 基本的な操作さえあれば実装できる ┃ 独自エディタ 三種類の実装方式がある
高度な編集機能は実装毎に書く必要があり大変 ┃source-editor.jsm Firefox 11 より利用可能 ソースコードエディタに対する統一的なインタフェース