徒書

2003年5月分。


Googleのキャッシュに挿入されるtableを何とかする

Googleは日頃大いに活用させてもらっているのですが、検索結果からページを辿る際には、キーワードのハイライトがあることから、元のページではなくGoogleで保存されたキャッシュのページを見ることも多々あります。特にファイルサイズが大きい場合は、キーワードを見つけやすくするため、その傾向がより高いです。

そんなわけでキャッシュのページをよく見るのですが、正しいHTML+CSSで作成されたページのキャッシュを見た場合、あの上部に挿入されている、「これはGoogleのhttp://〜のキャッシュです」云々と書かれている枠(tableによる)が崩れた表示になってしまうことがたまにあります。

挿入されるtableとその内部はHTML的にかなり無茶苦茶なマークアップであり、またその挿入の仕方もかなり無理矢理なので、そこをなんとか改善してほしい……という気持ちはあるものの、一般利用者にとってはそんな事情は窺い知ることはできず、ただ「表示が崩れた」と見られるのみでありましょう。もしかするとその表示の崩れた理由が「CSSを使っているからだ」などと思われるかも知れず、そうなるのはちょいと癪です。ならばこちらで、キャッシュに挿入されるtableを整形してやればいいではないか、ということを思いつきました。勿論CSSを使って。

CSSの対応が比較的進んでいるMozilla(Gecko)系ブラウザやOperaへの対処は、さほど難しくはないです。Googleのキャッシュに挿入されるtable要素にはborderやらwidthやらの属性も付いてくるので、属性セレクタを使うことにより、自サイト内のtable要素に対するスタイルと区別すればよいわけです。

Googleキャッシュのtableは三重になっており、外側に二重のtable、あと、「これらのキーワードがハイライトされています」の部分でもう一つtableがあります。これらはそれぞれ外側から、

  1. <table border="1" width="100%">
  2. <table border="1" bgcolor="#ffffff" cellpadding="10" cellspacing="0" width="100%" color="#ffffff">
  3. <table border="0" cellpadding="0" cellspacing="0">

というタグになっています。当サイト内のtableではborder属性は(多分)使っていなかったので、子孫セレクタとの合わせ技で

  1. table[border="1"] { ... }
  2. table[border="1"] table[border="1"] { ... }
  3. table[border="1"] table[border="1"] table[border="0"] { ... }

という指定にしてみました。Operaでは、複数の属性を参照する属性セレクタ( table[border="1"][width="100%"] とか)が効かないようなので、その辺も考慮して。あと、tableの中にはbやらfontやらcodeやらのインライン要素も入っているので、それを逆に利用してスタイル指定してみたり。

で、取り敢えず対処前から対処後のようにすることができました。具体的なスタイル指定は当サイトCSSファイルの末尾の方を参照。

* * *

さてMozilla、Operaはいいとして、問題はIEであります。やはり多くのお客さんはIE利用者ですので、むしろこちらの方をぜひ対処したいのですが、IEでは属性セレクタが使えないというのが難点。せめて一番外側のtableにclass属性のひとつも付けてりゃいいのに、とGoogleへのうらみ言の一つも言いたくなるところ。

まあ、class属性がないなら付けるしかないでしょうなあ、というわけであまり使いたくなかった奥の手、JavaScriptの出番であります。ページ読み込み時に実行させているスクリプトに以下のコードを追加しました。

/* Googleのキャッシュで挿入されるtableにclass付けする */
function googleCacheClass() {
    if (!location.host.match(/(google|216\.239\.\d{2}\.100)/i)) return;
    gTable = document.getElementsByTagName('table').item(0);
    gTable.className = 'google-cache';
}

で、このclass付けされたtableを元にしたスタイル指定を更に追加。実際の指定についてはこちらも当サイトCSSファイルの末尾の方を参照下さい。これでIEにも(スクリプトが有効であれば)一応対処できました。

* * *

今回のこれは「いくらなんでもやり過ぎなのでは」と自分でも疑問だったりします。普通に閲覧する際にも大きくなったCSSファイルやスクリプトを読み込ませてしまうデメリットを考えると、あまりオススメはできません。と念のため追記。

(2003年5月11日)


鳥肌とか耳とか

「自分の意思で鳥肌を立たす」というのは果たして一般的な動作でありうるのでしょうか……という自分の先日の疑問について、しまけんさんより言及頂きました。

コレは無理です…。ど、どうやると出来るんでしょうコレ、操れると面白い気がするので。

ええと、やり方としては

  1. 延髄のあたりに意識を集中する。
  2. 鼻からゆっくりと息を吸い込むようにする。

てな感じで、これで全身にぞわわっとくるのですが、いかがでしょう。数十秒くらいなら鳥肌状態を維持することもできますが、あまりやると疲れます。

* * *

実は自分も耳を動かせるのですが、しまけんさんのように左右別々にまでは出来ず、両方同時にしか動かせないのです。幼少の折にもっと鍛錬しておけば勝てたのに!(←何にか)と後悔することしきりでありましたことよ。

(2003年5月13日)


WinIEでabbr要素を何とかする

WinIEがabbr要素を理解しないことへの対応として、The Web Kanzakiで用いられいてたスクリプトを少し変更したものを使ってました(参照: 見よう見まねJavascript)。それで今まで動作上特に問題もなく、またinnerHTMLと正規表現を使ってソースを書き替えるという手法はスクリプトの見た目もすっきりしていて分かりやすいのですが、別の手段として、正規のDOM的手法を用いてなんとかならないかと考えまして、試してみることにしました。DOMの勉強も兼ねて。

やり方としては、abbr要素ノードからその子テキストノードとtitle属性を取り出して、それを新しく作ったspan要素に適用し、span要素を文書に追加する、という感じで行けるかなと思っていたのですが、実際にやってみるとabbr要素の子ノードが取り出せなくて躓きました。色々と試してみる中で、確認のため、

<abbr title="world wide web">WWW</abbr>

というabbr要素ノードnに対し、n.outerHTMLをとってみたところ、このような結果に。

<ABBR title="world wide web">

あれ、要素の中身と終了タグはどこに? その行方を探すべくまた色々と試したところ、どうやら理屈が分かりました。

例えば以下のようなp要素:

<p>本日は<abbr title="world wide web">WWW</abbr>日和なり。</p>

について、その全ての子ノードを取り、各子ノードのnodeType, nodeName, nodeValueを確認してみたところ、WinIEでは以下のような結果となります。

順序nodeTypenodeNamenodeValue
03 (text)#text本日は
11 (element)ABBRnull
23 (text)#textWWW
31 (element)/ABBRnull
43 (text)#text日和なり。

つまりabbr要素の開始タグ部分は空要素のように扱われており、要素の子ノードになると思っていた"WWW"は空要素ノードのnextSiblingノード、さらにその弟ノードになってる終了タグ部分は"/ABBR"という不思議なタグ名を持つ空要素になっていると……。なるほど、道理でabbr要素に対してスタイルを適用できないわけだと納得。ちなみにabbrタグに限らず、WinIEが認識しない(HTMLの要素として存在しない)タグがソースにあった場合は、このような扱われ方になるようです。

一応、MozillaとOpera 7での場合も。こちらは流石に期待通りの結果となってます。

順序nodeTypenodeNamenodeValue
03 (text)#text本日は
11 (element)ABBRnull
23 (text)#text日和なり。

ともあれ、動作が多少変であってもabbr要素の中身部分をDOM的手段で(childでなくnextSiblingとして)取り出せることが分かったので、それを用いて新たにspan要素を作り、文書へ追加することは何とかできました。

が、ふと「スクリプトで新たにabbr要素を作って文書に追加したら、それはどのように扱われるのだろう」という考えがよぎりましたので試してみたところ、そうして作られたabbr要素はtitle属性がツールチップとして表示されるし、CSSによるスタイル適用もできるではありませんか。

そういうことであるのなら、何もspan要素なんかの助けを借りるまでもなく、もともとの妙な形で扱われているabbr要素をちゃんとしたabbr要素として生成しなおせばよいわけです。最終的には以下のようなスクリプトとなりました。

/*  abbr要素を再生成する(for WinIE) */
function regenerateAbbr() {
    var abbrs = document.getElementsByTagName('abbr');
    for (var i = 0; i < abbrs.length; i++) {
        var oldAbbr = abbrs.item(i);
        var newAbbr = document.createElement('abbr');
        newAbbr.title = oldAbbr.title;
        oldAbbr.parentNode.insertBefore(newAbbr, oldAbbr);
        while (oldAbbr.nextSibling.nodeName != '/ABBR') {
            newAbbr.appendChild(oldAbbr.nextSibling);
        }
        oldAbbr.parentNode.removeChild(oldAbbr.nextSibling);
        oldAbbr.parentNode.removeChild(oldAbbr);
        /*alert(newAbbr.parentNode.innerHTML);*//*確認用*/
    }
}

と、手間かけて作ってみたこのスクリプトなのですが、実は効率の点ではinnerHTMLを書き換える方法に劣ります。残念。しかしながらWinIEにもabbr要素をabbr要素として認識させることができる、という点に意義があるような気がするので、当サイトではしばらく前からこちらを使用しています。

(2003年5月15日)


QUERYからPATH_INFOへ変更

徒書の個別記事表示のURLを、/itazuragaki/?(記事id) から /itazuragaki/id/(記事id) に変更しました。とは言え今まで通り /itazuragaki/?(記事id) の方でアクセスしても、自動で /itazuragaki/id/(記事id) に移動しますので、ご迷惑はおかけしません。

これで現在徒書で使用しているCGIスクリプトは以下の3種となりました。

(2003年5月18日)


Re: XHTML1.1のMIMEタイプ

net::memoXHTML1.1のMIMEタイプについて。XHTML 1.1はtext/htmlでいいというのは自分も同意なのですが、以下の部分が気になりました。

また、meta要素でapplication/xhtml+xmlを宣言しておいて、サーバーが言うことを聞かないと言い訳するのもありだと思います。

meta要素のhttp-equiv属性は、サーバがHTTPレスポンスヘッダに用いる情報を収集するためのものとされていますが、サーバが必ずそのように動作しなければならないとは規定されていないと思います。実際、「meta要素を解析してその通りにHTTPヘッダを出力するサーバ」があるというのもあまり聞かないような(自分が知らないだけかもですが)。

なので、サーバがmeta要素の通りにHTTPヘッダを出してくれないからといって、必ずしもサーバが悪いとは言えないと思います。で、meta要素の通りにHTTPヘッダが出力されなければ、meta要素でのapplication/xhtml+xmlの指定も無意味なわけで、ただ無意味だけでなく、実際はtext/htmlで出力されているのだから嘘の情報を書いていることになってしまいます。そんな嘘を書くくらいだったら、application/xhtml+xmlにこだわらずに、meta要素でもtext/htmlと書く方がまだましよいのではないでしょうか。

あと、以前にsatosiiさんから伺ったことなのですが、XHTML Media Types邦訳)には

"XHTML を application/*+xml として serve する場合には、meta http-equiv での content-type 指定は記述すべきでない (SHOULD NOT) と" という注記 [2] があります。

という話もあります。XHTML Media Typesの文脈からすると「文字エンコーディングについて、meta要素での指定はすべきでない」という話と思われますが、meta要素でエンコーディングだけ指定してContent-Typeそのものは指定しない、というのは無理なので、やはり「application/xhtml+xmlとして提供される文書には、 <meta http-equiv="Content-Type" content="..." /> という指定自体書くべきでない」ということになると思います。

* * *

XHTML文書(1.1まで)の良いところは、今までにあったHTMLと同じタグ名を使っていることにあるように思います。だからこそ少し記述に気を遣えばHTML用ブラウザで表示することも可能だし、またその同じ文書をXML文書としてしかるべきアプリケーションで処理することも可能なわけで。そういった混成物hybridであることの利点を生かすには、まだ今しばらくはtext/htmlとして提供することにも十分意味があると考える次第であります。

……と、「text/htmlのXHTML文書」を肯定する派であることを表明してみたり。

(2003年5月29日)


2003年5月29日

先週あたりからどうも風邪気味です。今のところ症状は喉にしかきていないので普段の生活は維持していますが、頻繁に咳が出てくるのはちょっとつらいところ。つい先日になって喉飴で症状が軽減されることを覚えたので、最近では飴舐めまくりな日々であります。

(2003年5月29日)


mod_html_metaを使ってみる

Re: XHTML1.1のMIMEタイプで、「『meta要素を解析してその通りにHTTPヘッダを出力するサーバ』があるというのもあまり聞かないような」、などと無知なことを書いたところ、いわいさんよりApacheでの実装があるとのこと。

あまり聞かないような」に異論がある訳ではなく単なる FYI なのですが、Apache 用モジュールで mod_html_meta という実装はあります。試したことはないのですけど。

情報感謝です。ずっと「そのようなサーバの機能があるか」という観点で調べていたので、Apacheのモジュールを探すことには気付いていませんでした。ということでApacheのモジュール追加は初体験ながらも、自宅のCygwin + Apacheで実験。

  1. http://www.yoshidam.net/mod_xml_charset-0.1.5.tar.gz よりソースをダウンロードして展開。

  2. 説明の通りに apxs -c mod_html_meta.c でコンパイルしてみる。

  3. 途中でエラーになってしまった。

    $ apxs -c mod_html_meta.c
    gcc -DCYGWIN -DUSE_HSREGEX -DEAPI  -DSHARED_CORE -DSHARED_MODULE -I/usr/include/
    apache  -c mod_html_meta.c
    mod_html_meta.c:134: conflicting types for `strndup'
    /usr/include/string.h:63: previous declaration of `strndup'
    apxs:Break: Command failed with rc=1
  4. strndupという名前が衝突しているようなので、mod_html_meta.c の中の"strndup"を試しに"strnndup"と書き換えてみる(←いいのか)。

  5. それで再度コンパイルしてみると最後まで通って、mod_html_meta.dll ができた。

  6. できたdllを、apxs -i -a mod_html_meta.dll でインストール。

  7. httpd.confにmod_html_metaモジュールが追加されたことを確認し、Apache再起動。

  8. .htaccessに以下2行を追記。

    HTMLMeta on
    AddHTMLMeta html

んでもって手打ちtelnetでApacheサーバにHEADリクエストを出してみると……あ、確かにmeta要素での指定が反映されましたよ。

$ telnet localhost 80
Trying 127.0.0.1...
Connected to croquis.
Escape character is '^]'.
HEAD /kits/tanpen/ HTTP/1.0

HTTP/1.1 200 OK
Date: Thu, 29 May 2003 14:47:11 GMT
Server: Apache/1.3.24 (Cygwin)
Content-Script-Type: text/javascript           ←このへん
Content-Style-Type: text/css                   ←
Last-Modified: Mon, 26 May 2003 15:39:44 GMT
Connection: close
Content-Type: text/html; charset=Shift_JIS     ←

Connection closed by foreign host.

meta要素の指定で、Content-Typeまでも変更できるのかどうかが一番気になるところだったのですが、それも問題なくできていました。うーむすごい。ただし、meta要素をSSIで追加している場合だと、さすがにその部分の指定は反映できないようでした。

で、しばらくmeta要素の指定でtext/plainにしてHTMLソースをそのまま表示させてみたりとか、image/jpegにして「画像にエラーがあるよ」とエラー表示させてみたり(Mozillaにて)などして遊んでいました。

※コンパイルのしかたについてはもっといい方法がありそうな気がしますが……。

(2003年5月30日)


Re: XHTML1.1のMIMEタイプ(2)

net::memoのHTTPヘッダとmeta要素の擦れ違いへの返事です。或いは前回からの続き。

meta要素のContent-Typeはサーバーに対して書かれるもので、UAに対して書かれるものではありません。それに対し、HTTPヘッダはUAに対して送信されるものです。

meta要素でContent-Typeを書くことの第一の役割は、確かにその通りと思いますが、文書中にHTMLタグの形式で記述される以上、完全にHTTPサーバのためのみの情報とは言えないのではないでしょうか。

ブラウザでソースを見れば簡単に見ることができるし、その気になればDOMでmeta要素の中からhttp-equiv="Content-Type"であるものを探し、そのcontent属性の内容を参照する、ということも可能なので、UAに対しても提供される情報のひとつではあると思います。

ですから、HTTPヘッダがtext/htmlでmeta要素がapplication/xhtml+xmlだったとしても、その文書が text/htmlとapplication/xhtml+xmlの両方に適合しているのであれば、サーバーもXHTML文書も間違っているとは言えません。サーバーがmeta要素を利用しなかっただけで、XHTML文書が嘘をついているわけではありません。

Content-Typeについて、文書がそのメディアタイプに適合しているかというのは、直接には関係ないのでは。例えば、終了タグ書き忘れミスのあるHTML/XHTML文書をContent-Type: application/xhtml+xml、またはContent-Type: text/htmlで送信することも可能ではあり、その場合、application/xhtml+xmlであればエラーを表示し、text/htmlであればエラーはある程度無視しつつそれなりに文書を整形して表示することでしょう(Mozillaの場合)。これは指定されたメディアタイプによって、ブラウザが文書の扱い方を変えた結果そうなったわけです。そのように、ブラウザ(UA)に文書をどのように扱ってほしいかを示すのが、HTTPレスポンスヘッダのContent-Typeの役割と思います。

なので、(HTTPヘッダで)Content-Type: text/htmlとして提供された文書の中に <meta http-equiv="Content-Type" content="application/xhtml+xml" /> と書いてあるというのは、文書中で「この文書はメディアタイプをapplication/xhtml+xmlとして提供してます」と書いてあることになり、やはり嘘の情報になってしまうと思います。

……と長々と述べてますが、結局のところは、

そうは言っても、meta要素だけをapplication/xhtml+xmlにすることを推奨するつもりはありません。HTTPヘッダとmeta要素の内容が食い違うのは事実で、そのような状態を好ましいとは思わないからです。

というのに賛成なのでして、好ましいと思わないからこそ、meta要素でapplication/xhtml+xmlの指定は書くべきでない、と考えるのです。

* * *

以下、2003-06-02 - Hatena::agendaでの指摘より削除……

更に言えば、「XHTML文書のメディアタイプはapplication/xhtml+xmlとすべき(should)」ということを勧めているXHTML Media Types邦訳)という文書の、正にその中で、「application/(xhtml+)xmlの文書ではmeta http-equivによる指定はすべきでない(should not)」という旨が述べられています。この一点だけでも、meta要素でapplication/xhtml+xmlの指定は書くべきでない理由としては十分、と思います。

XHTML Media Typesの勧めに従うのであれば、

  • HTTPヘッダでContent-Type: application/xhtml+xmlを出力する。
  • meta要素でのapplication/xhtml+xmlの指定は書かない。

とするのが最善なわけで、

  • HTTPヘッダではContent-Type: text/html。
  • meta要素でapplication/xhtml+xmlの指定を書いている。

というのはXHTML Media Typesの勧めるところを二つもそむいている状態であり、背くのなら背くでいい(sholud或いはshould notなので)としても、だったら何故application/xhtml+xmlなどと書くのか? 一体どちらをしたいのか? と見られかねないのではないでしょうか。

……削除ここまで

* * *

HTTPヘッダでContent-Typeが何と出力されているか、というのは、CGIスクリプトのHTTPヘッダを出力させる部分に触れたりとか、Apacheの設定を変えてみたりとか、telnetを使って手入力でHTTPリクエストを送ってみたりとかしてみないと、ただHTML文書を書いているだけではなかなかぴんとこない部分であるように思います。「meta要素でのContent-Type指定がHTTPヘッダにも反映される」というサーバの実装が必ずしも多数派でない以上、「Content-Typeはmeta要素で指定すればそれだけでOK」という誤解を文書製作者へ広めないためにも、XHTML文書にmeta要素でapplication/xhtml+xmlの指定は書くべきでないと考えます。

※ 実際には、HTTPヘッダとして出力されていなければ全く意味がないわけで。

……と、以上が仕様書などを読んで自分が考えたことなのですが、ウェブでそんな主張をしている文章はあまりないようなので不安でもあり、他のXHTML利用者のご意見をぜひ伺いたいところ。

参照

meta要素でのapplication/xhtml+xmlの指定を勧めているところ

(2003年6月1日)


2003年5月31日の観劇

ネットで知り合って実際に会った人、というのは自分にはほとんどいないのですが、その数少なくも貴重な知人の一人であるおかみさん主宰のBHUコントライブへこの日は行きました。折りしも颱風の最中でしたが比較的近所だしそんなに大変なこともなかろう、と外へ出てみると雨が止みつつあり丁度よい時でありました。

会場についてみると既にほぼ満席状態。渡されたパンフレットにはクロスワードパズルがついており、上演を待つ間に今回のコント五題のタイトルを当てる趣向。あいにく書くものが無かったので記憶力を頼りに解こうとしたのですが、時間が足りず、全てのタイトルが判明する前にライブが始まってしまい、やや心残りながらも舞台へ注目。以下タイトルと感想を。

ガーディアン
恋人とデートする娘のため、三人の背後霊(親戚)が彼女の行動を良い方向に操作しようとするが……。ラストの落ちは、後からじわじわっときました。小説とかにも向いた落ちであるかも。
コターケ
芸術家なのにとことん漫才ネタにこだわりあまつさえ他人にもそれを強要するコターケ氏。前回のライブでこの空軍パイロット版を見ていたこともあり、大いに楽しみました。ピカソ&ゴッホのネタ的新解釈には思わず納得しつつ笑。
タクヤ
子供の出産を病院の待合室で待つ父親。しかし生まれた子供は体重61000ろくまんいっせんg、白いガウンに身をつつみ、自らの足で歩いてきて挨拶も流暢にこなす男だった。途惑う父親(そりゃそーだ)だが、なんとか息子との感動の対面を果たそうとする……。ちょっと長いかなという気もしましたが、最初から最後まで楽しみました。思わず「自分が父親の立場だったらどうするだろう」とか考えてみたり。
プー
これについては説明するのが勿体無いというか。見所は何と言ってもおかみさん扮する「プーさん」の登場シーン。科白一つで全てを了解させる説得力がスゴイ。前回の「スイスロボ」以来の衝撃でありました。ラストが(意外にも)ハッピーエンドだったのも良かったです。
ピラペーン
緑の服を身にまとったピラペーンとお供の妖精、他BHUメンバーも総出演でのショートネタの連続。畳み掛けられるネタの勢いに圧倒されました。あと妖精さんの衣装にはちょっと眼が惹か……イヤイヤ。ところで「ピラペーン」がPeter Panの早口発音だということには翌日になって漸く気付きました。見ている間も「ピーターパンだなあ」と思っていた筈なのに迂闊。
その他
幕間で登場(ビデオにて)する司令官コマンダーカーネーヅカー氏(幕間ごとにBHUメンバーに指令を与えるという役割)の怪演もまた楽しみました。ビデオの切れ方がまた絶妙で、切れるたびに会場の笑いを誘っていましたよ。

次のBHU公演にも期待してます。コントライブは勿論、先のGWに女子高演劇部により初演されたという「パパパ・ピピピ」も是非おかみさん出演/演出で見てみたいところ。

i n s p i r e d !に、「パパパ・ピピピ」初演時の写真つきレポートがあります。

(2003年6月2日)


北村曉 kits@akatsukinishisu.net