XULのtextboxのオートコンプリート 【追記あり】
XULのtextboxには"Toolkit autocomplete"という仕組みがあります.
textbox (Toolkit autocomplete) - Mozilla | MDN
これを使うと, 入力履歴からの自動補完などが簡単に実現できます. しかし, フォームの入力履歴からの補完で少しつまってしまったので, ここにメモしときます.
基本
type="autocomplete" autocompletesearch="history"/>
こんな風に, type属性に"autocomplete"と指定してあげるだけで自動補完してくれるようになります. autocompletesearch属性には, どの情報から補完するかを指定します. 指定できるのは以下の3種類のようです.
- history: ロケーションバーのurl入力履歴から補完します.
- form-history: フォームの入力履歴から補完します.
- file: ファイル名から補完します. ローカルのファイルからのようです.
スペース区切りで複数指定もできます. これらとは別に独自のデータから補完させたい場合は, XPCOMのコンポーネントを書かないといけません. 詳しくは下のチュートリアルをどうぞ.
How to implement a custom autocomplete search component - Mozilla | MDN
form-historyの使い方
autocompletesearchが"history"の場合は, 本当にtextboxの属性を加えるだけでokなんですが, form-historyの場合は少しjsの方にも手を加える必要があります.
まずはxulの方の説明から. "type", "autocompletesearch"に加えて"autocompletesearchparam"という属性も追加します. これはフォームを識別するラベルのようなもののようです.
id="my-form" type="autocomplete" autocompletesearch="form-history" autocompletesearchparam="my-form-history"/>
次にjsのコード. "Components.interfaces.nsIFormHistory2"というコンポーネントのaddEntry()というメソッドに, 先ほどのautocompletesearchparamで指定した名前と追加したい文字を渡します. こうすることで, 渡した文字列が履歴として保存されます. textboxのonkeypressやフォームのsubmitボタンなどに, このコードを呼び出す関数を渡しておくと, フォームにテキストが入力される度にそのテキストが履歴として保存されていきます. これだけで補完してくれるようになります.
function addFormHistory() { var entry = document.getElementById('my-form').value; var formHistory = Components.classes["@mozilla.org/satchel/form-history;1"] .getService(Components.interfaces.nsIFormHistory2 || Components.interfaces.nsIFormHistory); formHistory.addEntry("my-form-history", entry); }
こちらのコード例も参考にしてください.
xul - Save drop-down history in a Firefox Toolbar - Stack Overflow
こちらのchaikaという2chブラウザのコードも参考にさせてもらいました.
nsIFormHistory
(下の節に追記あり. あわせてお読みください. 2010-02-20)
一つ謎だったのが, nsIFormHistoryというコンポーネントです. 手元の環境(Firefox 3.6, Mac OSX)でこのコンポーネントを呼び出すと, 以下のエラーが返ってきました.
Error: Component returned failure code: 0x80570018 (NS_ERROR_XPC_BAD_IID) [nsIJSCID.getService]
代わりにnsIFormHistory2を呼び出すとうまく動作しました. よくわからないのですが, 上記のstackoverflowの解答で,
.getService(Components.interfaces.nsIFormHistory2 || Components.interfaces.nsIFormHistory);
と両方に対応できるようにしていたので, 現状これを真似しています.
追記(2010-02-20)
"nsIFormHistory"は現在もう無いそうです.
Firefox1.5までは"nsIFormHistory"だったのですが, Firefox2.0より"nsIFormHistory2"に変わったようです.
mozilla1.8 mozilla/toolkit/components/satchel/public/nsIFormHistory.idl (Firefox2.0)
mozilla1.8.0 mozilla/toolkit/components/satchel/public/nsIFormHistory.idl (Firefox1.5)
というわけで, Firefox2.0以降に対応するだけだったら, nsIFormHistory2にしておけば大丈夫のようです.
var formHistory = Components.classes["@mozilla.org/satchel/form-history;1"] .getService(Components.interfaces.nsIFormHistory2);
コメントにてid:piro_orさんに教えていただきました. ありがとうございます!