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
その節約、円になってますか?
isamumumu
1
700
TSX の <Hoge<Fuga>> という構文に驚いた話 / tsx-type-argument-syntax
kanaru0928
0
210
Go 1.27 における memory allocation の高速化
andpad
0
100
生成AIで帳票OCRが「簡単に」作れる時代になった?
kon_shou
0
620
霧の中の代数的エフェクト
funnyycat
1
490
【やさしく解説 設計編・中級 #1】一つの車に、運転手は一人 ~ある倉庫システムの事例から~
panda728
PRO
0
210
OpenSpecのproposalにbrainstormingを持たせてみた
tigertora7571
1
210
ドリフトを絶対に許さない(?)CDK運用 / CDK Ops with Zero Tolerance for Drifts (?)
akihisaikeda
1
180
Foundation Models frameworkで画像分析
ryodeveloper
1
600
Detecting Compromised CI with eBPF and Cilium Tetragon
lizrice
0
160
ITヒヤリハットを整理してみた ~ライフサイクルと原因から考える再発防止策~
koukimiura
1
140
ルールを書いて終わらせないハーネスエンジニアリング
yug1224
4
1.9k
Featured
See All Featured
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
123
22k
Getting science done with accelerated Python computing platforms
jacobtomlinson
2
400
SEO in 2025: How to Prepare for the Future of Search
ipullrank
3
3.7k
Building the Perfect Custom Keyboard
takai
2
830
GitHub's CSS Performance
jonrohan
1033
470k
Introduction to Domain-Driven Design and Collaborative software design
baasie
1
930
The Art of Programming - Codeland 2020
erikaheidi
57
14k
Intergalactic Javascript Robots from Outer Space
tanoku
273
27k
Amusing Abliteration
ianozsvald
1
240
Navigating Weather and Climate Data
rabernat
0
460
Jess Joyce - The Pitfalls of Following Frameworks
techseoconnect
PRO
1
330
Organizational Design Perspectives: An Ontology of Organizational Design Elements
kimpetersen
PRO
1
790
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 より利用可能 ソースコードエディタに対する統一的なインタフェース