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
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
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
46
16k
Other Decks in Programming
See All in Programming
AI時代のUIはどこへ行く?その2!
yusukebe
19
6.9k
Webフレームワークの ベンチマークについて
yusukebe
0
150
TAKTでAI駆動開発の品質を設計する
j5ik2o
6
1.1k
Hunting Vulnerabilities in Symfony with LLMs
vinceamstoutz
0
430
Composerを使ったサプライチェーン攻撃の様子を眺めてみる #phpstudy
o0h
PRO
2
240
Dataformのリポジトリを立ち上げるときにまずやること / dataform-day0-2026
snhryt
0
120
Old Dog, New Tricks: The Java 25 Reinvention - JNation
bazlur_rahman
0
150
PHPで使える日時の表現と、その知り方 #frontend_phpcon_do
o0h
PRO
0
210
The Arts and Crafts of Work in the AI Era — Toward Mastery in Software Development
kuranuki
1
730
Spring Security 実践 ─ GraphQL APIで実務に役立つ 認証・認可 を学ぶ
wagyu
0
200
Vite+ Unified Toolchain for the Web
naokihaba
0
130
TSKaigi Night Talks 2026_TypeScriptでサプライチェーンの整合性を型に閉じ込める
geekplus_tech
0
330
Featured
See All Featured
Bootstrapping a Software Product
garrettdimon
PRO
307
120k
Visual Storytelling: How to be a Superhuman Communicator
reverentgeek
2
550
GraphQLとの向き合い方2022年版
quramy
50
15k
How STYLIGHT went responsive
nonsquared
100
6.2k
エンジニアに許された特別な時間の終わり
watany
107
250k
Designing Experiences People Love
moore
143
24k
SEO Brein meetup: CTRL+C is not how to scale international SEO
lindahogenes
1
2.7k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
12
1.2k
Why Mistakes Are the Best Teachers: Turning Failure into a Pathway for Growth
auna
0
150
The Pragmatic Product Professional
lauravandoore
37
7.3k
Design of three-dimensional binary manipulators for pick-and-place task avoiding obstacles (IECON2024)
konakalab
0
450
Scaling GitHub
holman
464
140k
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 より利用可能 ソースコードエディタに対する統一的なインタフェース