jQueryのプラグインとして動作する、WYSIWYGでないマークアップテキストエディターmarkItUp!の低機能版を作成した。
これまたより大きなアプリへの組み込みを前提にしたもので、スタイルをjQuery UIのCSS Frameworkに依存しているので、概観の統一ができる。また先に作成公開したjquery.tedit.js同様に、オブジェクトとしてもjQuery要素としても操れるようにしてみた。
2009年8月30日日曜日
Opera9.46とjQuery1.3.2、TEXTAREA要素の値を利用する際の注意
Windows版Opera 9.46、jQuery 1.3.2の環境でのことであるが、改行を含むTEXTAREAの値を、DOM要素のvalueプロパティから得るか、jQuery要素のvalメソッドから得るかで、値の内容が異なることがわかった。
よくわからないが、改行文字に関連するらしい。
改行が存在する文字列の場合、jQueryのvalメソッドで得られる文字列の長さは、DOMのvalueプロパティで得られる文字列の長さより、改行の数分短い。
jQueryのソースコードをみると、valメソッド内では、DOM要素のvalueプロパティで得た文字列のなかの「\r」(復帰文字?)を取り除く処理が行われているから、これが原因かと思う。おそらくOSごと、ブラウザごとに得られる値が異なるのでは困る、ということでこうした標準化処理を行っているのだろう。これ自体は親切な機能である。
ただ今回このTEXTAREA要素の値を利用するのが、ほかならぬこの要素内の文字列の選択範囲の情報(選択範囲の開始や終了の位置、キャレットの位置など)を取得する、というものであったため問題が起きた。
[追記 2009/8/30]
Opera 9.64 ではTEXTAREA要素内の文字列の選択範囲操作のとき、「\r」(復帰文字)の存在を考慮して、選択開始位置、終了位置などの文字数を調整する必要がある──でないと他のブラウザとの間で挙動に差が生じる──が、IEではむしろ「\r」の存在は考慮しないほうがよいらしい。Opera同様に「\r」を1文字と数えて調整を行うと、逆に他のブラウザとの間で挙動がズレてしまう(すくなくともIE8ではそうであった)。
よくわからないが、改行文字に関連するらしい。
改行が存在する文字列の場合、jQueryのvalメソッドで得られる文字列の長さは、DOMのvalueプロパティで得られる文字列の長さより、改行の数分短い。
jQueryのソースコードをみると、valメソッド内では、DOM要素のvalueプロパティで得た文字列のなかの「\r」(復帰文字?)を取り除く処理が行われているから、これが原因かと思う。おそらくOSごと、ブラウザごとに得られる値が異なるのでは困る、ということでこうした標準化処理を行っているのだろう。これ自体は親切な機能である。
ただ今回このTEXTAREA要素の値を利用するのが、ほかならぬこの要素内の文字列の選択範囲の情報(選択範囲の開始や終了の位置、キャレットの位置など)を取得する、というものであったため問題が起きた。
[追記 2009/8/30]
Opera 9.64 ではTEXTAREA要素内の文字列の選択範囲操作のとき、「\r」(復帰文字)の存在を考慮して、選択開始位置、終了位置などの文字数を調整する必要がある──でないと他のブラウザとの間で挙動に差が生じる──が、IEではむしろ「\r」の存在は考慮しないほうがよいらしい。Opera同様に「\r」を1文字と数えて調整を行うと、逆に他のブラウザとの間で挙動がズレてしまう(すくなくともIE8ではそうであった)。
2009年8月27日木曜日
久々に拡張機能ScribeFireを導入してみると
久々に拡張機能ScribeFire(バージョン3.4.4)を導入してみると、小さなウィンドウで(開発者たちが想定していないウィンドウの高さで)SbribeFireを起動すると、ブラウザウィンドウのタブ内に表示されたScribeFireのUI全体が縦にスクロールできてしまう、という問題が解決していた。
しかし拡張機能Web Search Pro──選択文字列をドラッグすると、画面内に、登録された複数の検索エンジンの“窓枠”が表示され、そこへドロップすると検索が行われる機能など検索関連で多彩な機能をもつ──とは相性が悪い。
ScribeFireのUI内の投稿テキストの編集画面で、文書中に画像を挿入して、この画像の位置を変えようとドラッグすると、Web Search ProのUIがScribeFireのUI上に表示されてしまう。しかも検索エンジンの“窓枠”のかたちが崩れ、巨大化していて、画面の過半を隠してしまう… よってこの2つの拡張機能の併用は、(Web Search Proのドラッグ&ドロップ検索の機能をOffにしないかぎり)難しい。
あと、投稿テキストの編集画面の上側に表示されるタブは相変わらず日本語非対応らしく、横幅の調整ができていない。これは相変わらずである。
しかし拡張機能Web Search Pro──選択文字列をドラッグすると、画面内に、登録された複数の検索エンジンの“窓枠”が表示され、そこへドロップすると検索が行われる機能など検索関連で多彩な機能をもつ──とは相性が悪い。
ScribeFireのUI内の投稿テキストの編集画面で、文書中に画像を挿入して、この画像の位置を変えようとドラッグすると、Web Search ProのUIがScribeFireのUI上に表示されてしまう。しかも検索エンジンの“窓枠”のかたちが崩れ、巨大化していて、画面の過半を隠してしまう… よってこの2つの拡張機能の併用は、(Web Search Proのドラッグ&ドロップ検索の機能をOffにしないかぎり)難しい。
あと、投稿テキストの編集画面の上側に表示されるタブは相変わらず日本語非対応らしく、横幅の調整ができていない。これは相変わらずである。
Powered by ScribeFire.
2009年8月26日水曜日
jQueryUIのSelectableにバグ?
jQueryのUIプラグインにふくまれるSelectableプラグインにはどうもバグのようなものがある。
(jQuery 1.3.2、jQuery UI 1.7.2、Firefox 3.5)
■親子(孫)関係にある要素で「選択」動作が混乱
要素A、B、C、D、E、…という順番で入れ子構造になっているHTMLの要素(たとえばDIV要素)があって、
このようにした状態で、要素Eをクリックしても、「選択」(select)イベントは起きない。そしてなぜか、selectingイベント中、要素Cが「選択」イベントの対象となる。
これは例えばselectingイベントリスナの第2引数であるuiオブジェクトのselectingプロパティを参照するとこれがわかる。
またFirebug等でDOMとしての要素Cを監視していると、要素Eがクリックされたとき、(要素Eではなく要素Cに)"ui-selecting"クラスが付加され、マウスクリックが終わってもそのまま残されることがわかる(本来はselectingイベントが終了したのだから自動的に"ui-selecting"は取り除かれなくてはいけない。この不完全な動作が、Selectableプラグイン内部で問題の起きている証拠?)。
「選択」動作が終了すると、selectstopイベントは起きる。けれども、要素Eに(その要素が「選択」されたことを示す)"ui-selected"クラスが付加されることはない。
どういう理由か分からないが、Selectableプラグインの内部では、「5」の段階でも、選択可能な要素の一覧として、要素C(たち)の情報が何らかのかたちで残存してしまっているらしい。
■この問題を回避する方法
「回避する方法」といってもかなり奥の手的なのだが…、手順「4」のあと、Aのhtmlメソッドを呼び出して、Aの内側のHTML要素を文字列のかたちで取り出し、それをそのままAのhtmlメソッドに渡す( A . html( A . html() ) )。そして手順「5」を実施する。
こうすると、BやCやDやE(のどこか)に要素(DOM)に結びつけられている「選択」可能な要素の情報が破棄されて、うまくいく。…みたい。
(jQuery 1.3.2、jQuery UI 1.7.2、Firefox 3.5)
■親子(孫)関係にある要素で「選択」動作が混乱
要素A、B、C、D、E、…という順番で入れ子構造になっているHTMLの要素(たとえばDIV要素)があって、
- 要素Dのselectableメソッドを呼び出して、要素E(たち)を選択できるようにする( D . selectable ( [ {Object} options ] ) )。
- 要素Dのselectableメソッドを、文字列"destroy"を引数にして呼び出して、Eの選択可能状態を解消する(D . selectable ( "destroy" ))。
- 次に要素Bに対して、selectableメソッドを呼び出して、要素C(たち)を選択可能にする。
- 要素Bのselectableメソッドを、文字列"destroy"を引数にして呼び出して、Cの選択可能状態を解消する。
- もう一度、要素Dのselectableメソッドを呼び出して、要素E(たち)を選択できるようにする。
このようにした状態で、要素Eをクリックしても、「選択」(select)イベントは起きない。そしてなぜか、selectingイベント中、要素Cが「選択」イベントの対象となる。
これは例えばselectingイベントリスナの第2引数であるuiオブジェクトのselectingプロパティを参照するとこれがわかる。
またFirebug等でDOMとしての要素Cを監視していると、要素Eがクリックされたとき、(要素Eではなく要素Cに)"ui-selecting"クラスが付加され、マウスクリックが終わってもそのまま残されることがわかる(本来はselectingイベントが終了したのだから自動的に"ui-selecting"は取り除かれなくてはいけない。この不完全な動作が、Selectableプラグイン内部で問題の起きている証拠?)。
「選択」動作が終了すると、selectstopイベントは起きる。けれども、要素Eに(その要素が「選択」されたことを示す)"ui-selected"クラスが付加されることはない。
どういう理由か分からないが、Selectableプラグインの内部では、「5」の段階でも、選択可能な要素の一覧として、要素C(たち)の情報が何らかのかたちで残存してしまっているらしい。
■この問題を回避する方法
「回避する方法」といってもかなり奥の手的なのだが…、手順「4」のあと、Aのhtmlメソッドを呼び出して、Aの内側のHTML要素を文字列のかたちで取り出し、それをそのままAのhtmlメソッドに渡す( A . html( A . html() ) )。そして手順「5」を実施する。
こうすると、BやCやDやE(のどこか)に要素(DOM)に結びつけられている「選択」可能な要素の情報が破棄されて、うまくいく。…みたい。
2009年8月25日火曜日
新しいことと、これまで通りのこと
■新しいこと
衆院選挙が近づいてきて──というか先の都議会選挙前後からずっとそうなのであるが──、わが家の近辺では幸福実現党の青シャツ衆が毎日のように活動している。
何しろマニフェストがうたう政策というのがめちゃくちゃで、あまりにもヒドイので、オヤは毎日のように憤慨している。(ちなみに党名だけで見ると、「みんなの党」よりはマシではないか、などと思ってしまう。なぜいっそのこと、「国民戦線」とか「民衆運動連合」とかにしなかったのだろうか。そういう意味ではない? ならどういう意味なのだ。)
今朝のニュースでは、その、贈与税や相続税を廃すると堂々と宣言している政党の候補が、小泉息子候補を「世襲」(つまりあらゆる形態の“資本”の、遺産相続もしくは生前贈与)を理由に攻撃しているようすが見られた。こういう噴飯ものを見せられると、目が醒めてよいのはたしか。(血圧操縦の法?)
■これまで通りのこと
今回の選挙でも例のごとく「若者の投票率の低さ」が問題にされている。
若者の意見が政治に反映されないことが問題である──などというけれども、「意見」がないものは言えない。「意見」がないのにあえて言おうとするとNHKのニュースキャスターのようになるのである。(あるいはニュースステーションの古館のようになる、と言い換えてもよい。「意見」を言う準備のない私たちにも「説教」はできる。)
ニュースのナレータがいう「若者の意見」というのが一体何のことを指しているのか、いまいちわからない(たぶんナレータ自身、原稿執筆者自身よくわかっていない)。しかし、「誰それの意見」というのが繁華街の街頭インタビューで、おじさんやおばさんやおにいさんたちがテレビカメラに向かってしゃべっているようなことのことをいうなら、だいぶ簡単である。
ようするに「どの政党が与党になっても一緒」(無気力症の患者の悲壮な告白)、「国政を担える政党(候補)がほかにない」(最悪の食わず嫌い)、「言ったことをきちんと実現できる候補に投票したい」(完ペキな白紙委任状)。あるいは「やはりこういうときは“時局”向けのことでも言ってあげた方が良いだろうか?」。
結局だれが「意見」を述べているというのだろう? 街頭インタビューのようすを見るかぎり「若者の意見」という以前に、ほとんどのひとは──聞かれたときにそれに答える準備ができているという意味で──「意見」を持ってはいないのである。
しかしこれは当然のことではないか、と思う。そしてそうであるにもかかわらず、「若者」が倫理的に非難されるのには、イライラさせられる。白紙委任状の総数が増えたところで何がおこるだろうか? 何も起こらないか、せいぜいがまた日本を「ぶっこわす」候補や政党が当選して、野党の質問にニヤニヤ笑いの不真面目顔で答弁したりするのを毎朝のニュースで拝むことが出来る、その程度ではないだろうか?
大した「意見」がないなら、言うべきではない。しかし「意見がない」という状態を問題にすることは有意味である。実際、国政の利害関係者は有権者すべて(そして選挙権を与えられていない国内在住者すべて)である。にもかかわらず棄権や(さまざまなかたちで)白紙委任状を差し出さねばならない人びとがおびただしく存在することは、重大問題である。
「若者」云々いうのも、例えば──若者は斯く斯く然々の(現在もしくは将来の)悲惨のなかにおり、彼らの多くはこの問題の原因に気付いていない、だから彼らに彼ら自身の置かれている状況を理解させ、彼らを組織して、問題を政治的に解決しなくてはならない──というのならばわかる。けれどもNHKなどがいうのは、こういう種類の「意見」ではない。だからうんざりさせられるのである。
衆院選挙が近づいてきて──というか先の都議会選挙前後からずっとそうなのであるが──、わが家の近辺では幸福実現党の青シャツ衆が毎日のように活動している。
何しろマニフェストがうたう政策というのがめちゃくちゃで、あまりにもヒドイので、オヤは毎日のように憤慨している。(ちなみに党名だけで見ると、「みんなの党」よりはマシではないか、などと思ってしまう。なぜいっそのこと、「国民戦線」とか「民衆運動連合」とかにしなかったのだろうか。そういう意味ではない? ならどういう意味なのだ。)
今朝のニュースでは、その、贈与税や相続税を廃すると堂々と宣言している政党の候補が、小泉息子候補を「世襲」(つまりあらゆる形態の“資本”の、遺産相続もしくは生前贈与)を理由に攻撃しているようすが見られた。こういう噴飯ものを見せられると、目が醒めてよいのはたしか。(血圧操縦の法?)
■これまで通りのこと
今回の選挙でも例のごとく「若者の投票率の低さ」が問題にされている。
若者の意見が政治に反映されないことが問題である──などというけれども、「意見」がないものは言えない。「意見」がないのにあえて言おうとするとNHKのニュースキャスターのようになるのである。(あるいはニュースステーションの古館のようになる、と言い換えてもよい。「意見」を言う準備のない私たちにも「説教」はできる。)
ニュースのナレータがいう「若者の意見」というのが一体何のことを指しているのか、いまいちわからない(たぶんナレータ自身、原稿執筆者自身よくわかっていない)。しかし、「誰それの意見」というのが繁華街の街頭インタビューで、おじさんやおばさんやおにいさんたちがテレビカメラに向かってしゃべっているようなことのことをいうなら、だいぶ簡単である。
ようするに「どの政党が与党になっても一緒」(無気力症の患者の悲壮な告白)、「国政を担える政党(候補)がほかにない」(最悪の食わず嫌い)、「言ったことをきちんと実現できる候補に投票したい」(完ペキな白紙委任状)。あるいは「やはりこういうときは“時局”向けのことでも言ってあげた方が良いだろうか?」。
結局だれが「意見」を述べているというのだろう? 街頭インタビューのようすを見るかぎり「若者の意見」という以前に、ほとんどのひとは──聞かれたときにそれに答える準備ができているという意味で──「意見」を持ってはいないのである。
しかしこれは当然のことではないか、と思う。そしてそうであるにもかかわらず、「若者」が倫理的に非難されるのには、イライラさせられる。白紙委任状の総数が増えたところで何がおこるだろうか? 何も起こらないか、せいぜいがまた日本を「ぶっこわす」候補や政党が当選して、野党の質問にニヤニヤ笑いの不真面目顔で答弁したりするのを毎朝のニュースで拝むことが出来る、その程度ではないだろうか?
大した「意見」がないなら、言うべきではない。しかし「意見がない」という状態を問題にすることは有意味である。実際、国政の利害関係者は有権者すべて(そして選挙権を与えられていない国内在住者すべて)である。にもかかわらず棄権や(さまざまなかたちで)白紙委任状を差し出さねばならない人びとがおびただしく存在することは、重大問題である。
「若者」云々いうのも、例えば──若者は斯く斯く然々の(現在もしくは将来の)悲惨のなかにおり、彼らの多くはこの問題の原因に気付いていない、だから彼らに彼ら自身の置かれている状況を理解させ、彼らを組織して、問題を政治的に解決しなくてはならない──というのならばわかる。けれどもNHKなどがいうのは、こういう種類の「意見」ではない。だからうんざりさせられるのである。
2009年8月21日金曜日
jQuery UI Sortable とダブルクリック・イベント
jQuery UIプラグインについてのメモ。
バージョンは、jQuery 1.3.2、jQuery UI 1.7.2
jQuery UIプラグインのうちSelectableは、あらかじめ指定した要素をマウスのドラッグにより擬似的に選択できるようにしてくれる。
要素選択の動作中、点線で縁取られた透明のDIV要素(class属性はui-selectable-helper)を画面最前面に表示して、マウスカーソルの移動にあわせてこのDIVのサイズを変更、選択範囲を指定できるようになっている。そして選択動作(マウスのドラッグ動作)の終了後、その指定範囲にあった要素に選択されたことを示すclass属性(ui-selected)を追加する。
このSelectableの動作自体はすばらしいのだが、これによってSelectableの対象として指定した要素では、ダブルクリック(dblclick)などのイベントがキャンセルされてしまう。
現状では、Selectableにこれを回避するようなオプションは用意されていないので、擬似的に“ダブルクリック・イベント的状況”を判定するしかない。
バージョンは、jQuery 1.3.2、jQuery UI 1.7.2
jQuery UIプラグインのうちSelectableは、あらかじめ指定した要素をマウスのドラッグにより擬似的に選択できるようにしてくれる。
要素選択の動作中、点線で縁取られた透明のDIV要素(class属性はui-selectable-helper)を画面最前面に表示して、マウスカーソルの移動にあわせてこのDIVのサイズを変更、選択範囲を指定できるようになっている。そして選択動作(マウスのドラッグ動作)の終了後、その指定範囲にあった要素に選択されたことを示すclass属性(ui-selected)を追加する。
このSelectableの動作自体はすばらしいのだが、これによってSelectableの対象として指定した要素では、ダブルクリック(dblclick)などのイベントがキャンセルされてしまう。
現状では、Selectableにこれを回避するようなオプションは用意されていないので、擬似的に“ダブルクリック・イベント的状況”を判定するしかない。
var prev_target;
var dblclick_callback = function(...){ ... };
var selectable = $({String} selector) . selectable({
stop: function(event){
var selected = $('.ui-selected', selectable);/* stop イベントには、引数として選択された要素へのアクセス手段が提供される、ということがないので一々選択されている要素を取得 */
if(selected.length === 1){ /* 選択されている要素が1つだけ*/
if(prev_target /* 前回の選択要素が保持されていて(undefinedでなくて)、*/
&& selected.get(0) === prev_target /* 前回の要素と今回のそれが同じ */){
var dblclick_event = ... /* 必要ならばカスタム・イベントオブジェクトなどを作成 */
dblclick_callback . call(prev_target, dblclick_event, {selected: selected});/* (疑似)ダブルクリックイベント用のイベントリスナ関数を呼び出す */
}else{ /* 前回の選択要素が保持されていない場合 */
prev_target = selected.get(0);
window.setTimeout(function(){ prev_target = undefined; }, 250); /* 一定時間(この場合250ミリ秒)経過したら、この回の選択要素への参照を削除 */
}
}
/* 以降は本来の選択動作についての処理を適当に */
}
});
2009年8月19日水曜日
jQueryのプラグインをつくった
この2週間ほどで2つのjQueryプラグインをつくった。
おかげでまた一段とIEのことを知ることができて、“有益”であった…
■jquery.indent.js
指定されたHTML要素の内側のHTMLソースコードや、文字列のかたちで与えられたソースコードを、人間に見やすいようにインデントして返すもの。
(実はもうすこし前につくったものが結構バグがあり、非効率でもあったので全面的に書き直したもの)
■jquery.tedit.js
HTMLのTABLE要素をグラフィカルに編集するためのプラグイン。行・列の挿入・移動・削除、セルの結合・分割、コピペなどの編集と、編集結果を二重配列やTABLE要素として返す機能を持たせた。
どちらもより大きなアプリに組み込むことを前提に開発したが、そちらの完成時期は不明。友人のアドバイスにしたがってデモページをつくったりもした。
おかげでまた一段とIEのことを知ることができて、“有益”であった…
■jquery.indent.js
指定されたHTML要素の内側のHTMLソースコードや、文字列のかたちで与えられたソースコードを、人間に見やすいようにインデントして返すもの。
(実はもうすこし前につくったものが結構バグがあり、非効率でもあったので全面的に書き直したもの)
■jquery.tedit.js
HTMLのTABLE要素をグラフィカルに編集するためのプラグイン。行・列の挿入・移動・削除、セルの結合・分割、コピペなどの編集と、編集結果を二重配列やTABLE要素として返す機能を持たせた。
どちらもより大きなアプリに組み込むことを前提に開発したが、そちらの完成時期は不明。友人のアドバイスにしたがってデモページをつくったりもした。
2009年8月18日火曜日
COLSPAN属性およびROWSPAN属性とIE
引き続きInternetExplorerのDOM実装と格闘していて気がついたこと。
■COLSPANとROWSPANは静的な値である?
jQueryが、IE6やIE7において、内部的にどのようにこの2つの属性を読み書きしているのかはわからないが、
という呼び出しで、DOMのTD要素に両属性を書き込みしても、ブラウザの画面内で表示されているTD要素にその効果──すなわち複数のセルを結合した大セルの表示と、それにともなう右隣、下隣のセルの適切な位置への移動──は行われない。
FirfoxやOpera、Safariで同じことをすれば、セルのサイズが変更される。つまり両属性を書き込んだ時点でそのTD要素を内包するTABLE要素の再レンダリングが行われて、前述の「効果」が現れる。(「効果」によって右や下方に押し出されてしまう余分なセルは削除すれば、きれいなテーブルになる)。
IEでは──すくなくともjQuery1.3.2を使用している場合──このような親切は期待できない。上記のattrメソッドで属性を書き込んだあと、TABLE要素に対して、
などとすこしばかばかしい処理(TABLE要素内のHTMLソースコードを取り出して、それをそのまままた元のTABLE要素内に注入する)をして、手動でTABLEの再レンダリングを引き起こす必要がある。
※TABLE要素内の要素にイベントリスナなど後天的・動的に付加された情報がある場合、それらの情報は上記の処理では棄却されてしまう。これを回避するにはもっと面倒な処理を行う必要がある。
■COLSPANとROWSPANは別待遇
これはFirefoxでもそうなのだが、COLSPANとROWSPANはブラウザ内部では値の扱い方が違うらしい。FirefoxではCOLSPANやROWSPANが指定されていない要素に対して、たとえば
これは標準と照らしてどうなのかわからないが、わかりづらい動作であることは確かであろうと思う。
IEではこれがさらに怪しげになる。
"colSpan"属性や"rowSpan"属性(なぜかSが大文字)が存在する。どういうときにこれらの属性値が出現するのかわからない。たぶん、
■そもそもIEでは、"colSpan"や"rowSpan"は存在しても、"colspan"や"rowspan"は存在しない?
さらに恐ろしいのは、IEで
などとすると、エラーでJavaScriptの実行が停止してしまうこと。
おそらく「そんな名前の属性は存在しません」とでも訴えているのである。これにはかなりムカっとくる。
■COLSPANとROWSPANは静的な値である?
jQueryが、IE6やIE7において、内部的にどのようにこの2つの属性を読み書きしているのかはわからないが、
( {jQuery} tdElement ).attr( 'colspan', {Number} colspanValue )
( {jQuery} tdElement ).attr( 'rowspan', {Number} rowspanValue )
という呼び出しで、DOMのTD要素に両属性を書き込みしても、ブラウザの画面内で表示されているTD要素にその効果──すなわち複数のセルを結合した大セルの表示と、それにともなう右隣、下隣のセルの適切な位置への移動──は行われない。
FirfoxやOpera、Safariで同じことをすれば、セルのサイズが変更される。つまり両属性を書き込んだ時点でそのTD要素を内包するTABLE要素の再レンダリングが行われて、前述の「効果」が現れる。(「効果」によって右や下方に押し出されてしまう余分なセルは削除すれば、きれいなテーブルになる)。
IEでは──すくなくともjQuery1.3.2を使用している場合──このような親切は期待できない。上記のattrメソッドで属性を書き込んだあと、TABLE要素に対して、
({jQuery} tableElement).html( ({jQuery} tableElement).html() )
などとすこしばかばかしい処理(TABLE要素内のHTMLソースコードを取り出して、それをそのまままた元のTABLE要素内に注入する)をして、手動でTABLEの再レンダリングを引き起こす必要がある。
※TABLE要素内の要素にイベントリスナなど後天的・動的に付加された情報がある場合、それらの情報は上記の処理では棄却されてしまう。これを回避するにはもっと面倒な処理を行う必要がある。
■COLSPANとROWSPANは別待遇
これはFirefoxでもそうなのだが、COLSPANとROWSPANはブラウザ内部では値の扱い方が違うらしい。FirefoxではCOLSPANやROWSPANが指定されていない要素に対して、たとえば
var td = $('<td></td>');とattrメソッドを呼び出した場合、二つの属性で返される値が異なる。
td.attr('colspan'); // undefined を返す
td.attr('rospan'); // 1 を返す
これは標準と照らしてどうなのかわからないが、わかりづらい動作であることは確かであろうと思う。
IEではこれがさらに怪しげになる。
"colSpan"属性や"rowSpan"属性(なぜかSが大文字)が存在する。どういうときにこれらの属性値が出現するのかわからない。たぶん、
td.attr('colspan', {Number} colspanValue);などとすると、(TABLE要素のinnerHTMLプロパティなどにアクセスするとわかるのだが)、TD要素に、この謎の属性が出現する。そしてなぜかこの謎の属性のほうが、"colspan"や"rowspan"(もちろんすべて小文字!)よりも効果が優先される。仕方なく、
td.attr('rowspan', {Number} rowspanValue);
if($.browser.msie){などとすると、うまくいく。($.browserつまりjQuery.browserオブジェクトは、jQuery1.3ではすでにサポート対象外宣告を受けているのだけど、こうしてしばしば立派に活躍していることを考えると、なぜサポート対象外?と疑問を感じる)
td.attr('colSpan', {Number} colspanValue);
td.attr('rowSpan', {Number} rowspanValue);
}
■そもそもIEでは、"colSpan"や"rowSpan"は存在しても、"colspan"や"rowspan"は存在しない?
さらに恐ろしいのは、IEで
td.removeAttr('colspan');
td.removeAttr('rowspan');
などとすると、エラーでJavaScriptの実行が停止してしまうこと。
おそらく「そんな名前の属性は存在しません」とでも訴えているのである。これにはかなりムカっとくる。
InternetExplorerのDOM属性認識
ここのところJavaScriptのライブラリjQueryのプラグインをいくつも作っていて気がついたのだが、InternetExplorer(IE)のJavaScript(JScript?)におけるDOM要素や、そのinnerHTMLプロパティからアクセスできるHTMLソースコードには独特なものがある。
Firefox、SafariではinnerHTMLプロパティからアクセスできるソースコードはタグ名がすべて小文字アルファベットで、XHTML的。ただしBR要素やHR要素、IMG要素などの元来閉じタグのない要素について末尾を「~/>」で終わらせる、というようなことはされていない。
Operaではある意味、innerHTMLというプロパティ名からして正しい挙動なのかもしれないが、タグ名はすべて大文字になる。
IEでは、innerHTMLプロパティから得られるソースコードは、Opera同様タグ名が大文字になる。そして属性値は、値にスペースが入らない種類のものである限り、「"~"」(クオテーション)で囲われていない。さらに、STYLE属性の、CSSプロパティ名がなぜかみな大文字アルファベットになっている。
これはDOM要素の属性にアクセスするためのプロパティを通じて、STYLE属性にアクセスした場合も同様であるらしい。CSSプロパティ名は大文字であった。
以上でもすでにして、IEのDOMが恐ろしくなってくるのだが、さらに問題があった。
IEでは手書きのソースコードや、DOMのメソッドを用いて作成したDOM要素に、手動で指定してはいない数多くの──おびただしい数の属性が追加される。innerHTMLプロパティを用いるにせよ、attributesプロパティを用いるにせよ、これらのプロパティによって得られるソースコードや属性の情報にはこちらが予期していない、しかもものすごい数の属性が含まれている。
たとえばTD要素(テーブルのセル)のcolspan、rowspanなどはこちらが指定しなくても、DOMのプロパティとしては存在していて、初期値は1。disabledという属性を持つことのできる要素については、かならず「disabled=false」。その他のすべての要素には「tabindex=1」が勝手にセットされているし、「on~」という形式のイベントリスナを指定する属性も空文字列が値として指定されて存在している。
これは結構タチが悪く、ソースコードがやたらと長く、また読みにくくなるし、下手に標準値などを指定されると困る場面がある(IEのDOMから得られたソースコードを他のブラウザで利用するときなど)。
結局上記4ブラウザでHTMLソースコードを標準化する(そして何らかの別の処理に用いる)には、
──という処理が必要になる。
Firefox、SafariではinnerHTMLプロパティからアクセスできるソースコードはタグ名がすべて小文字アルファベットで、XHTML的。ただしBR要素やHR要素、IMG要素などの元来閉じタグのない要素について末尾を「~/>」で終わらせる、というようなことはされていない。
Operaではある意味、innerHTMLというプロパティ名からして正しい挙動なのかもしれないが、タグ名はすべて大文字になる。
IEでは、innerHTMLプロパティから得られるソースコードは、Opera同様タグ名が大文字になる。そして属性値は、値にスペースが入らない種類のものである限り、「"~"」(クオテーション)で囲われていない。さらに、STYLE属性の、CSSプロパティ名がなぜかみな大文字アルファベットになっている。
これはDOM要素の属性にアクセスするためのプロパティを通じて、STYLE属性にアクセスした場合も同様であるらしい。CSSプロパティ名は大文字であった。
以上でもすでにして、IEのDOMが恐ろしくなってくるのだが、さらに問題があった。
IEでは手書きのソースコードや、DOMのメソッドを用いて作成したDOM要素に、手動で指定してはいない数多くの──おびただしい数の属性が追加される。innerHTMLプロパティを用いるにせよ、attributesプロパティを用いるにせよ、これらのプロパティによって得られるソースコードや属性の情報にはこちらが予期していない、しかもものすごい数の属性が含まれている。
たとえばTD要素(テーブルのセル)のcolspan、rowspanなどはこちらが指定しなくても、DOMのプロパティとしては存在していて、初期値は1。disabledという属性を持つことのできる要素については、かならず「disabled=false」。その他のすべての要素には「tabindex=1」が勝手にセットされているし、「on~」という形式のイベントリスナを指定する属性も空文字列が値として指定されて存在している。
これは結構タチが悪く、ソースコードがやたらと長く、また読みにくくなるし、下手に標準値などを指定されると困る場面がある(IEのDOMから得られたソースコードを他のブラウザで利用するときなど)。
結局上記4ブラウザでHTMLソースコードを標準化する(そして何らかの別の処理に用いる)には、
- IEとOperaでは、タグ名の小文字化を実施し、
- IEでは、「"~"」で囲われていない属性値を囲い、
- IEでは、STYLE属性についてはCSSプロパティ名部分を小文字化し、
- IEでは、さらに値が「0」であったり、「false」や「null」、「""」(空文字列)であるような属性は、(属性値だけでなく)属性ごとカットしてしまい、これは場合にもよるが「tabindex」については「1」であればこれも属性ごと削除する
──という処理が必要になる。
拡張機能Abduction!がFirefox3.5に対応
閲覧中のウェブページのスクリーンショットを作成してくれる拡張機能Abduction!が、Firefox3.5に対応した。
この拡張機能は、数あるスクリーンショット作成拡張機能のうちでも、ページ内の画像として取得する範囲を指定できるという便利なものであったが、Firefoxがバージョン3.0から3.5にバージョンアップして以来、この拡張機能は非対応となって使用できなくなっていた。しかし、今日ふと拡張機能の配布ページを見に行ったところ、バージョン3.5に対応していた。
インストールしてみると、ユーザーインターフェースが改良されていて、前のバージョン(Firefox3.5非対応)では拡張機能の画面(スクリーンショットとして取得する範囲を指定できる)がFirefox本体のウィンドウとは別ウィンドウとして表示されていたのだが、最新版では本体ウィンドウに統合されている。
しかも現在閲覧中のページ──スクリーンショットを撮りたいページ──の画面(タブ)はそのままに、画面上部にバーが表示され、画面内には、閲覧中のページの内容に重ねるかたちで半透明の選択範囲が表示されている。選択範囲をダブルクリックすると対象がページ全体になる。
なるほどインターフェースの改良を行っていたので対応が遅れたのか…と納得。すばらしい出来であると思う。
2009年8月11日火曜日
NTEmacs にJavaScript編集モード“js2-mode”を導入
Emacsのことで、友人はJavaScript編集時にJava編集用のモードを使用していると言っていたが、なるほどEmacsには標準で、JavaScriptやCSSを編集するためのモードが付属していない模様。「~.js」ファイルを開いてみると、“cc-mode”(C言語向けモード?)がオンになった。
CもJavaもやらないのにこれらのモードを使用せねばならないのでは、そもそもEmacsの導入を考えた目的であるところのものの半分──低機能-軽快なEmEditorと、高機能-鈍重なAptanaの間を埋めること──が満たせない。
■js2-mode
そこでまたググったところ、“js2-mode”というものを見つけた。(その名も“javascript-mode”なるものも広汎に用いられている──られていた?──らしいが、強調表示の不完全さの指摘が散見されたのでこちらはやめ)
“js2-mode”はここからダウンロードできる。
ダウンロードしたファイルは、「js2-(日付)(アルファベット).el」という感じの名前になっているので、これを、「js2.el」という名前に変更。
NTEmacsでは、バージョンナンバーのディレクトリ(「22.2」)の中の、「site-lisp」ディレクトリ内に、上記ファイルを移動。
Emacsを起動し、「M-x byte-compile-file」とコマンドを入力、ファイル名として「js2.el」の絶対パスを指定。すると、コンパイルが行われて、「js2.elc」なるファイルが出来る。
Emacs上で「M-x js2-mode」とモードを指定するコマンドを打つと、“js2-mode”が有効になる。
また.jsファイルを読み込んだときに自動でjs2-modeが適用されるようにするため、「.emacs」ファイルを編集する。自分の環境(Windows Vista Business SP2)では、同ファイルは、「C:\Users\(user name)\AppData\Roaming」に存在した。編集内容は下のページを参考にした。
【参考】
CもJavaもやらないのにこれらのモードを使用せねばならないのでは、そもそもEmacsの導入を考えた目的であるところのものの半分──低機能-軽快なEmEditorと、高機能-鈍重なAptanaの間を埋めること──が満たせない。
■js2-mode
そこでまたググったところ、“js2-mode”というものを見つけた。(その名も“javascript-mode”なるものも広汎に用いられている──られていた?──らしいが、強調表示の不完全さの指摘が散見されたのでこちらはやめ)
“js2-mode”はここからダウンロードできる。
ダウンロードしたファイルは、「js2-(日付)(アルファベット).el」という感じの名前になっているので、これを、「js2.el」という名前に変更。
NTEmacsでは、バージョンナンバーのディレクトリ(「22.2」)の中の、「site-lisp」ディレクトリ内に、上記ファイルを移動。
Emacsを起動し、「M-x byte-compile-file」とコマンドを入力、ファイル名として「js2.el」の絶対パスを指定。すると、コンパイルが行われて、「js2.elc」なるファイルが出来る。
Emacs上で「M-x js2-mode」とモードを指定するコマンドを打つと、“js2-mode”が有効になる。
また.jsファイルを読み込んだときに自動でjs2-modeが適用されるようにするため、「.emacs」ファイルを編集する。自分の環境(Windows Vista Business SP2)では、同ファイルは、「C:\Users\(user name)\AppData\Roaming」に存在した。編集内容は下のページを参考にした。
【参考】
NTEmacs 22 インストール・メモ
Lisp/Scheme系言語の学習のため、また愛用のEmEditorと仕方なく使用しているAptanaの間を埋めるテキストエディタ探しのため、Emacsを試してみようということになった。マニュアルを貸してくれた友人に感謝。
今回はそのGNU EmacsおよびNTEmacsのインストールのときのメモ。
環境は、Windows Vista Business SP2。
■GNU Emacs 23.1
FSFで配布されているGNU Emacsを試した。Windows版は、こことかから。最新版をダウンロードして、任意のディレクトリに解凍するだけでよい。解凍してできたディレクトリのなかの、「bin」ディレクトリの「runemacs.exe」でEmacsを起動する。
起動してみたところ、少なくともバージョン23.1では、日本語のインライン入力に対応していないことがわかった。日本語入力をすると、Emacsウィンドウ(“フレーム”といふらしい)の下に入力中のテキストが表示される。確定するとEmacs画面中のポインタ箇所に挿入される仕組みである模様(そもそも確定動作以前にインライン入力ができないことがわかった段階で失望を感じてそれ以上なにもしなかった)。一昔前のPhotoshopがこんな感じだったように思う。
チュートリアルの画面も、日本語フォントが不完全なものなのか、対応するフォントがないことをしめすらしい「□」がいっぱい混じっている。虫食いの古文書か、ところどころ判読できない古新聞史料でも読んでいるみたいで、話にならない。
これを初心者が使うのは時間と労力の無駄になるだろうと判断して(初心者でなくてもインライン入力ができないのでは、テキストエディタとして問題、だと思う)、このオリジナルEmacsは放棄。
■NTEmacs 22.2
上述のフォントのことですこしググったときに見つけた、GNU Emacsにパッチを当てたエディション、NTEmacs。
日本語のインライン入力ができる上、ウィンドウ(フレーム)の半透明表示ができるらしい(しかし後者の機能はあまり重要でない)。
ダウンロードはSOURCEFORGEのプロジェクトページから。一覧中「~.patch.gz」などで終わっているのは無視して、「NTEmacs 22BASE Binary」などと表示されている欄からダウンロード。「emacs_22.2_bin_20080327.exe」は自己解凍プログラムだったので、ダブルクリックで解凍できる。
これまた好きな場所に移す。解凍してできたディレクトリのなかの「22.2」ディレクトリのなかの、「bin」に「runemacs.exe」がある。
起動するとちゃんと日本語のインライン入力ができる。フォントの設定も適切にされていて、MSゴシックで表示される。前述のような文字の欠落はない。
一段落。
今回はそのGNU EmacsおよびNTEmacsのインストールのときのメモ。
環境は、Windows Vista Business SP2。
■GNU Emacs 23.1
FSFで配布されているGNU Emacsを試した。Windows版は、こことかから。最新版をダウンロードして、任意のディレクトリに解凍するだけでよい。解凍してできたディレクトリのなかの、「bin」ディレクトリの「runemacs.exe」でEmacsを起動する。
起動してみたところ、少なくともバージョン23.1では、日本語のインライン入力に対応していないことがわかった。日本語入力をすると、Emacsウィンドウ(“フレーム”といふらしい)の下に入力中のテキストが表示される。確定するとEmacs画面中のポインタ箇所に挿入される仕組みである模様(そもそも確定動作以前にインライン入力ができないことがわかった段階で失望を感じてそれ以上なにもしなかった)。一昔前のPhotoshopがこんな感じだったように思う。
チュートリアルの画面も、日本語フォントが不完全なものなのか、対応するフォントがないことをしめすらしい「□」がいっぱい混じっている。虫食いの古文書か、ところどころ判読できない古新聞史料でも読んでいるみたいで、話にならない。
これを初心者が使うのは時間と労力の無駄になるだろうと判断して(初心者でなくてもインライン入力ができないのでは、テキストエディタとして問題、だと思う)、このオリジナルEmacsは放棄。
■NTEmacs 22.2
上述のフォントのことですこしググったときに見つけた、GNU Emacsにパッチを当てたエディション、NTEmacs。
日本語のインライン入力ができる上、ウィンドウ(フレーム)の半透明表示ができるらしい(しかし後者の機能はあまり重要でない)。
ダウンロードはSOURCEFORGEのプロジェクトページから。一覧中「~.patch.gz」などで終わっているのは無視して、「NTEmacs 22BASE Binary」などと表示されている欄からダウンロード。「emacs_22.2_bin_20080327.exe」は自己解凍プログラムだったので、ダブルクリックで解凍できる。
これまた好きな場所に移す。解凍してできたディレクトリのなかの「22.2」ディレクトリのなかの、「bin」に「runemacs.exe」がある。
起動するとちゃんと日本語のインライン入力ができる。フォントの設定も適切にされていて、MSゴシックで表示される。前述のような文字の欠落はない。
一段落。
2009年8月10日月曜日
Nos enfants nous accuserons
割引の効能のあるチラシを手に入れて、つい先日公開の映画、『未来の食卓』を観てきた。雑誌『ふらんす』でも紹介されていたが、原題の“Nos enfants nous accuserons”(ノ・ザンフォン・ヌ・ザキュズロン:子どもたちはわれわれを非難するだろう)というほうがやはり映画の内容にマッチしているような気がする。日本ではあまりウケなさそうな文字列だけど。
自治体による学校給食、高齢者向け給食サービスの無農薬・無化学肥料化および地産地消化の実例を紹介する映画で、化学物質の生産者・消費者双方への悪影響が繰り返し論じられている点などを鑑み。
映画中で盛んに登場する「bio」(ビォ)の語。映画を観るまで、なにか勘違いしていて、毒々しいイメージを持っていたのだが、「自然農法」の意であった(produits bios[自然農法作物]、culture biologique[自然農法])。そういえばそういう名前の乳製品をスーパーで見かけたことがあるような気がするが、あれはあまり「bio」ではなさそう(別の意味のbio)。
フランスの片田舎の小学生たちの、元気に授業を受けたり給食を食べたりしているのを観ていたらすこし元気が出た :-)
自治体による学校給食、高齢者向け給食サービスの無農薬・無化学肥料化および地産地消化の実例を紹介する映画で、化学物質の生産者・消費者双方への悪影響が繰り返し論じられている点などを鑑み。
映画中で盛んに登場する「bio」(ビォ)の語。映画を観るまで、なにか勘違いしていて、毒々しいイメージを持っていたのだが、「自然農法」の意であった(produits bios[自然農法作物]、culture biologique[自然農法])。そういえばそういう名前の乳製品をスーパーで見かけたことがあるような気がするが、あれはあまり「bio」ではなさそう(別の意味のbio)。
フランスの片田舎の小学生たちの、元気に授業を受けたり給食を食べたりしているのを観ていたらすこし元気が出た :-)
登録:
投稿 (Atom)