何日かマウスを使っていないのでブラウザ(Firefox)のキーボードインターフェイスが気になる。
Firefoxの設定で「オプション > 詳細 > 一般 > アクセシビリティ > キー入力時に検索を開始する」を有効にすると、Ctrl+Fやスラッシュを押してからでなくとも、目に付いた単語をタイプするだけでインクリメンタルなページ内検索が行える。このとき検索結果の文字列にフォーカスが移動するのが非常に都合が良くて、リンク文字列がアルファベットであればタブキーを使って順番にフォーカスを移動するよりスムーズにリンクにフォーカスをあててページを移動できる。
Firefoxの拡張機能のひとつである Mouseless Browsingもまたキーボードを使ったナビゲーションを円滑にする。そのアプローチは全てのリンクにシリアルナンバーを割り振るというもの。リンクの右下隅に表示される数字をタイプして Enterを押すとリンク先に移動し、Enterの代わりにプラスキーを押すと新しいタブで開くといった具合。
ところで、「オプション > 詳細 > 一般 > アクセシビリティ > キー入力時に検索を開始する」と Mouseless Browsingは競合する。数字をタイプすると両方が同時に動き出すのだ。
最初は、Mouseless Browsingにはシリアルナンバーを割り振ることだけを任せて、Find As You Typeで数字をタイプしてリンクにフォーカスを合わせ、リンクをクリックするのは Enter(新しいタブで開くなら Ctrl+Enter。どちらも Windows版 Firefoxの標準割り当て)、でうまくいくように思えた。実際、悪くない動作をする。
唯一、気に入らないのはスクロール位置がガタガタ移動するのが避けられないこと。例えば 125番のリンクをクリックしようと [1][2][5][Enter]とタイプすると、Enterを押すまでの間に、1番のリンク、12番のリンク、125番のリンクの順にフォーカスが移動しスクロール位置も合わせて移動するので見てて疲れる。前にも書いたが、フォーカスの移動に伴ってスクロール位置が移動するのはストレス。目の見える自分にとってフォーカスをあてたい対象は今、見えている範囲にあるのだから。
原因は Find As You Typeがインクリメンタルな検索を行うことにあって、Mouseless Browsingならそういうことは起こらないのだが。
Mouseless Browsingは良くできたやつで、こいつの設定に「Use numpad exclusively for Mouseless Browsing」というのがある。これをチェックしておけば、テンキー以外のキーをタイプしたときは Find As You Type、テンキーを使ったときは Mouseless Browsing、とどちらも有効にしたまま棲み分けができる。テンキーを使う時にはスクロールの問題も起こらない。
ところがこれにも問題が。このチェックが有効だとフォームに数字を入力するときにテンキーが使えない。exclusiveだとはいってもフォーカスが文字入力可能な場所にあるときはキーボード入力を Firefoxの標準のハンドラに譲って欲しい。そんなわがままを可能にする修正が下の 4点。元がいいから変更も楽だった。
<Fx profile>*\extensions\{c0bcf963-624b-47fe-aa78-8cc02434cf32}\defaults\preferences\mlb_prefs.js の 13行目に一行挿入。(初期設定を追加)
12 pref("mouselessbrowsing.exclusiveNumpad", false); 13 pref("mouselessbrowsing.exclusiveNumpadUnlessWritable", false); 14 pref("mouselessbrowsing.executeAutomatic", false);
<Fx profile>\extensions\{c0bcf963-624b-47fe-aa78-8cc02434cf32}\chrome\mouselessbrowsing.jar\content\mouselessbrowsing\prefs.xul に 70-72行目を挿入。(設定画面に項目を追加)
67 <row> 68 <checkbox id="exclusiveNumpad" label="Use numpad exclusively for Mouseless Browsing" prefid="mouselessbrowsing.exclusiveNumpad" defaultValue="0"/> 69 </row> 70 <row> 71 <checkbox id="exclusiveNumpadUnlessWritable" style="margin-left:30px" label="Unless a writable element has focus" prefid="mouselessbrowsing.exclusiveNumpadUnlessWritable" defaultValue="0"/> 72 </row> 73 <row> 74 <checkbox id="executeAutomatic" label="Execute automatically without pressing Enter" prefid="mouselessbrowsing.executeAutomatic" defaultValue="false"/> 75 </row>
<Fx profile>\extensions\{c0bcf963-624b-47fe-aa78-8cc02434cf32}\chrome\mouselessbrowsing.jar\content\mouselessbrowsing\mouselessbrowsingInit.js に 164行目を追加。(設定の読み込み)
163 MLB_exclusiveUseOfNumpad = prefs.getBoolPref("mouselessbrowsing.exclusiveNumpad"); 164 MLB_exclusiveUseOfNumpadUnlessWritable = prefs.getBoolPref("mouselessbrowsing.exclusiveNumpadUnlessWritable"); 165 MLB_executeAutomaticEnabled = prefs.getBoolPref("mouselessbrowsing.executeAutomatic");
<Fx profile>\extensions\{c0bcf963-624b-47fe-aa78-8cc02434cf32}\chrome\mouselessbrowsing.jar\content\mouselessbrowsing\mouselessbrowsingEvent.js の 361行目を変更。(条件判定ロジックの変更)
361 return MLB_exclusiveUseOfNumpad && isNumpad;
↓
361 return MLB_exclusiveUseOfNumpad && isNumpad && 362 !(MLB_exclusiveUseOfNumpadUnlessWritable && Utils.isWritableElement(event.originalTarget));
う〜ん。満足。
* Firefoxのプロファイルフォルダ。%APPDATA%/Mozilla/Firefox/Profiles/xxxxxxxx.default
「PayPal Account Limitation !」というタイトルのメールが来た。64.12.117.14という IPアドレスから 3回アクセスがあったからアカウントを制限したので、ログインして制限を解除しろという英文のメール。
HTMLメールだったので本文中のリンクをクリック。そこでフィッシングサイトに誘導された可能性に気付いて、Googleで PayPalを検索して二番目に表示された www.paypal.comに移動。だが Google検索で上位に表示されたからといってそこがフィッシングサイトでないともいえない。何をもって情報の送信先の身許を判断すればよいのだろう。
などと迷ってるうちに、自分が PayPalのアカウントを持ってないことに気付いて終了。アホか。
アニメ、面白いです。だからマンガを買ったけど、でも一番は声が素晴らしい。普通っぽくてつぶやきが多くてツボ。
デスノートにしろ、レベルEにしろ、連載を追いかけるほど面白い漫画は案外手元になかったりする。レベルEには冨樫義博に期待する要素がコンパクトに詰まっている。
てんで性悪キューピッドは幽遊白書以前にジャンプで連載されていた。お色気系。未読。
単行本が出たときは高校生。1900円は高すぎた。文庫版は加筆があり、写真が一部差し替え。
松浦純菜シリーズ二作目。最近三作目がでた(『上手なミステリの書き方教えます』)。既に三冊が積読で結局一冊も読んでいない。未読作家は早く読んで、買いか否かを判断せねば。
『日の名残り』(カズオ・イシグロ)を読んでいて目にした。その2、3日前にもどこかの Webサイトで目にしていた。今日 3度目に目にしたので買ってみた。
onclickでごにょごにょする HTML要素があって、そいつに Tabキーでフォーカスをあてたいなと思ったときに最初に思いついたのが
<a href="javascript:void(0)">ほげほげ</a>*
のように Aタグで囲う方法。遅まきながら、この時初めてステータスバーに javascript:void(0)と表示される何もしないリンクの存在意義に気付いた。こいつがあると Tabキーでフォーカスをあてられるし、Enterキーでクリックすることもできる。そしてスクリプト(onclickハンドラ)で処理できる。簡単かつ使える範囲の広い方法。javascriptを切ってるブラウザではそもそも onclickハンドラが動かないから javascriptスキーマを使うことの是非は問われないし。onclickハンドラでキーボードとマウスをまとめて処理できることや、対応するブラウザの多さなど、書けば書くほどこれしかないって思えてくる。
次に考えついたのが、9日に "tabindexはフォーカスの順番を決めるだけのものではないのだなぁ。" と書いたように、IE(>=5.0)や Firefox1.5で、tabindexを付けることでリンクやフォームの部品以外の要素をフォーカス可能にする方法。
IEの場合、
<element>.tabIndex = 0 // 0 => フォーカス可能にはするが、タブオーダーは指定しない <element>.onkeypress = function(){ if(event.keyCode == 13) this.click() } // Enter->Click
で済むが、Firefoxの場合 click()が実装されてるエレメントがフォームの部品などに限られているので
<element>.tabIndex = 0 // 同上 <element>.onkeypress = function(event){ if(event.keyCode == 13) { var event2 = document.createEvent("MouseEvents"); event2.initMouseEvent("click", true, true, event.view, event.detail, event.screenX, event.screenY, event.clientX, event.clientY, event.ctrlKey, event.altKey, event.shiftKey, event.metaKey, 0, null); this.dispatchEvent(event2); } }
と、かなり冗長。
* href="" だとそのページ自身へ移動(=リロード)してしまう。void(0)以外に href="#" を使う流派もある様子(でもイマイチ)。
あるページを読んでいる。読み進んでいく。「次のページへ」というリンクがある。タブキーを押す。ページがギュンッと巻き戻って一番最初のリンク*にフォーカスが移動する。さらにタブを押す、押し続ける。サイドバーのリンクを順にたどってフォーカスがページ下方へ移動していく。やがてまたもページが巻き戻る。今度は本文中のリンクを順に下方にたどっていく。やっと「次のページへ」にたどり着く。
今見ているリンクにフォーカスを合わそうとしているのに、フォーカスはとんでもないところに飛んでいく。タブキーを押すことによってスクロール位置が変わるのが非常にストレス。タブキーでフォーカスが移動する先は現在表示されてる(フレームに収まってる)部分だけで良い。
HTML作成者が tabindexをリンクやフォームに割り振っていた場合 tabindexの小さい順にフォーカスが移動するのだった。tabindexが一つでも指定されていればそちらを優先すべきだな。(といっても、tabindexが指定されていて欲しいのは自分がよく使うページだけだけど。不特定の人に見せるのが目的のページで押し付けは良くない。)
tabindexはフォーカスの順番を決めるだけのものではないのだなぁ。
ありものは↓。
Mouseless Browsingを使っているが Find As You Typeと競合するのでテンキーを Mouseless Browsing専用にしている。そうすると、テキストフィールドに数字を入力するのが不便(テンキーが使えないので)。
自前でやる場合、次にフォーカスを得るエレメントがどれなのかを自前で探すのは避けたいところ。それをするんだったら greasemonkeyで onblurを捕まえて、次にフォーカスを得るエレメントを順に辿っていって、最初に見つかったブラウザのフレーム内に収まってる(=見えている)エレメントを focus()すればいいはず。
* 普通はソーステキスト中に一番最初に登場したもの。tabindexが指定されていれば最小の tabindexを与えられたもの。
知らない。知らないよこんな便利なコマンド。
EXPLAIN sql-statement;
ならドキュメントに載ってるけど、これが返すのは
0|Integer|5|0| 1|MustBeInt|0|0| 2|MemStore|0|0| 3|IfMemZero|0|25| 4|IfMemPos|0|8| 5|Pop|1|0| ……
みたいな SQLがコンパイルされた結果の、VMが逐一実行する命令のリストだから腰を据えないと解読できない。
それに対して
EXPLAIN QUERY PLAN sql-statement;
が返すのは
0|0|TABLE MyBooks USING PRIMARY KEY
みたいな、テーブルに対する問い合わせのリスト。インデックスが使われるのかどうかもわかる。
Amazonで「七竈」「七竃」「桜庭 一樹」「可愛そうな大人」、いずれを検索しても『少女七竈と七人の可愛そうな大人』は見つからない。ISBNで検索してやっと見つかる。4048737007。難儀なタイトルを付けたものだ。
と、そうではなくて、近所の本屋がだらしなくて 4軒まわっても本を見つけられなかった。Gyaoでドラマが配信されてる『少女には向かない職業』はその内の 3軒で平積みだったというのに。何故に新刊を隣に並べてまとめて売ろうとしない。
Rubyist Magazine - RubyKaigi2006特別号(6月10日 午前の部)より。
Ruby オンリーのカンファレンスを Ruby ゆかりの地・日本で開催できる喜びを寿ぎ*ました。
難易度高すぎ(笑) (゜Д゜;)ハッ!俺だけ?
* 再変換(ATOKの場合、文字入力が可能な場所で選択して Shift+変換)すると正解がわかる。