IE8βでもVMLを使えるように

category-icon

 こんばんは。Windows 7βを試用中ですが、写真をお洒落に見せるスクリプトLink (photoeffect.js)が、IE8βでエラーとなり意図した効果が得られないのを発見。調べてみると、IE8ベータがVMLをサポートしていないのが原因っぽいです。おそらく、正式版ではVMLはサポートされるとは思いますが、確証はないので(Silverlightとかあるし)、現時点での回避策を考えてみました。

 IE8には、3つのレンダリングモードがあり、(紆余曲折ありましたが)デフォルトではフル標準モードでレンダリングされます。じゃ、どんな時にQuirksモード(後方互換[1]の非標準モード)になるかというと、以下の場合です。

  1. 文書中に DOCTYPE宣言がない場合
  2. 文書型が HTML3.0以下の場合
  3. HTML4.0 TransitionalまたはFramesetのDOCTYPE宣言にURLを含まない場合

の3つです。詳しくは、SummerWind - IE8のレンダリングモードに関するまとめLink あたりを参照。

 今どきのブログシステムでは、これらに該当しない可能性が高く、IE8は標準モードで動きます。なので(少なくとも現時点では)VMLのスクリプトが動かないわけです。じゃ、どうするか? 簡単そうなのは、METAスイッチGを使うこと。とりあえずVMLはIE7モードでは問題なく作動するので、以下のようなmetaタグをwebページに追加すれば良いです。

<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />

 確かに、これは簡単だし現実的な解決法ですが、こうしちゃうと、JavaScriptもIE7モードになっちゃいます。IE8では、querySelectorAllなどのSelectors APIやらDOMオブジェクトに対するgetter/setter APILink など、面白そうなAPIがサポートされるのに、IE7モードで走らせると、それらが使えません。

 出来れば、IE8モードのままでVMLも有効にしたいです。こんなときに使えるのが、インラインフレーム<iframe>。最近、ちっとも更新されていないのが気がかりな Dean EdwardsのエントリーLink が参考になります。

 つまり、IE8なページの中で、sandbox化されたIE後方互換の環境を構築し、その中でVMLを走らせるわけです。実際のデモを見たほうが早いと思うので、IE8βでアクセスしてみて下さい。IE7でも動きます。

  → http://p2b.jp/demo/vml-IE8.htmlLink

 IE8やIE7では、どう見えるかイメージショットも載せておきます。

IE8-VML
画像の回転も簡単に出来る。

 ここでは、単に画像を出力させるVMLを、以下のように関数化しています。

function vmlImg(src, w, h, r){
 /*
 @src: 画像ファイルを指定 
 @  w: 表示させる横幅
 @  h: 縦幅
 @  r: 回転角度(オプション)、-360~360
 */
 var ifr = document.createElement("iframe");
 ifr.marginWidth= "0"; ifr.marginHeight= "0";
 ifr.scrolling = "no"; ifr.frameBorder = "0";
 ifr.style.width = w + "px"; ifr.style.height = h + "px";
 
 document.body.appendChild(ifr);
 var idoc = ifr.contentWindow.document;
 idoc.write(""); idoc.close(); // これがないと document.body は null になる
 if(idoc.namespaces){
  if(!idoc.namespaces.v){
   idoc.namespaces.add("v", "urn:schemas-microsoft-com:vml", "#default#VML" );
  }
 }
 idoc.body.style.backgroundColor = document.body.currentStyle.backgroundColor;
 var img = idoc.createElement('<v:image src="'+ src +'" />');
 var imgcss = img.style;
 imgcss.width = w + "px"; imgcss.height = h + "px";
 if(r){
  imgcss.rotation = r;
  ifr.style.width = 2 * w + "px"; ifr.style.height = 2 * h + "px";
 }
 idoc.body.appendChild(img);
}

 IE8版ではVMLが正式にサポートされるのを期待して、深追いはしません。

  • [1] 言葉の問題なので、本文とは関係ないですが、前方互換なのか後方互換なのか、上位互換なのか下位互換なのか訳わかめ。視点をどこに置くかの差ですし。IE8から見て、IE7以下は過去のものだから、それらに対する互換性ということで、後方互換みたいに使いましたが、何か違うような。まぁ、言いたいことが分かれば良いのかなって。[^]

— posted by martin at 09:43 am   commentComment [0]  pingTrackBack [0]

BLOCKQUOTE要素とCITE要素をめぐる考察

category-icon

 大晦日に書いていた記事ですが、なかなか時間が取れずこんな時季になりました。瑞祥新春(ずいしょうしんしゅん) 2009。今年もよろしくお願いします。

 とりあえず、以下の点について、現時点での考えを自分なりに纏めてみました。

  1. BLOCKQUOTE要素とCITE要素のグループ化
  2. CSSによるCITE属性やTITLE属性抽出の問題点
  3. 引用ブックマークレットの活用
  4. 参考リンク

1. BLOCKQUOTE要素とCITE要素のグループ化

 昔から、BLOCKQUOTE要素とCITE要素をどう扱うかについては悩ましい問題です(個人的に)。さて、いきなりですが、ここで簡単なクイズをば。XHTML1.0 Strictの仕様に則ると仮定して、考えてみて下さい。

Q. 以下のXHTML文法の間違いを指摘せよ。

<blockquote
 cite="http://martin.p2b.jp/200812-stream-of-life.html"
 title="いのちの流れ">
 日夜 私の血管を流れる 同じ命の流れが
 この世界を流れ 旋律に合わせて踊る
</blockquote>

 一見すると、BLOCKQUOTE要素に用いられるCITE属性(validなURIのみ可)も適切ですし、TITLE属性も付いてます(これらは必須ではありませんが)。問題は、その引用文です。単なるテキストですが、ブロック要素の直下には、インラインであるテキストは置くことが出来ません。なので、ここは、

<blockquote
 cite="http://martin.p2b.jp/200812-stream-of-life.html"
 title="いのちの流れ">
 <p>日夜 私の血管を流れる 同じ命の流れが
 この世界を流れ 旋律に合わせて踊る</p>
</blockquote>

とP要素などのブロックレベルでテキストを囲む必要があります。では、次はどうでしょうか。

<blockquote
 cite="http://martin.p2b.jp/200812-stream-of-life.html"
 title="いのちの流れ">
<p>日夜 私の血管を流れる 同じ命の流れが
 この世界を流れ 旋律に合わせて踊る</p>
<cite>
 <a href="http://martin.p2b.jp/200812-stream-of-life.html">
 「生命潮流」より抜粋
 </a>
</cite>
</blockquote>

 現時点で、CITE属性に与えられたリンクを適切に処理するブラウザはないようなので(ケータイ除く)、読み手に分かりやすいように、CITE要素を使って、リンクを用意しました。先ず、ここで問題となるのが、BLOCKQUOTE要素の中にCITE要素を含めて良いのか? ですが、これは後で考えるとして、少なくとも、文法エラーではありません。問題は、CITE要素(≠属性)です。CITE要素はインラインレベルなので、これも、最初と同じように、P要素などで囲ってやる必要があります。CITE属性とCITE要素とは、全く別ものであることに留意して下さい。

<blockquote
 cite="http://martin.p2b.jp/200812-stream-of-life.html"
 title="いのちの流れ">
<p>日夜 私の血管を流れる 同じ命の流れが
 この世界を流れ 旋律に合わせて踊る</p>
<p><cite>
 <a href="http://martin.p2b.jp/200812-stream-of-life.html">
 「生命潮流」
 </a>
</cite>より抜粋</p>
</blockquote>

 では、先ほど述べた、BLOCKQUOTE要素の中のCITE要素の扱いですが、色んな意見があるようです。神崎氏は、「引用の方法」についてのセクションで次のように述べています。

引用の方法Link 」より抜粋

出典を示すcite要素の位置は、文法的には特に定められていません。ただし、この例のようにblockquote要素内で引用元を示すと、引用部分をコピー/ペーストする、あるいはスクリプトで引用部分を抽出するといった操作を行う時に、出典が不明にならないというメリットがあります。逆にcite要素を外に置くと、引用部分(blockquote)と出典を直接結びつける方法はなく、プログラムはその関係を単純に理解することはできません。要素をどこにおくべきか判断に迷う時は、どうやって利用されるのかを想像してみると、答えが出てくることがあります。

引用元: The Web KANZAKI: 強調,引用,グループ化,画像などの要素Link

神崎氏は、この実例として、以下のような引用を例示しています。

<p>次に、文学作品を引用する。</p>
<blockquote>
<p>吾輩は猫である。名前はまだない。…</p>
<p><cite>夏目漱石『吾輩は猫である』</cite></p>
</blockquote>
<p>この引用文を読んで、次の設問に答えなさい etc...</p>

引用元: 強調,引用,グループ化,画像などの要素 -- ごく簡単なHTMLの説明Link

 確かに、この場合は BLOCKQUOTE要素の属性であるCITE属性は使えません。出典がWeb上のリソースではないからです。[1]しかしながら、W3Cの定義によれば、BLOCKQUOTE要素は、(ブロックレベルの)引用のために準備されたものLink であって、それ以上の解釈をしないという立場に立てば、BLOCKQUOTE要素の中に、引用への参照を表すCITE要素を含めるのは、何となく落ち着きません。この辺りは、もはや各人の好みの問題ですし、どちらでも良い気もしますが、個人的にはBLOCKQUOTE要素の外にCITE要素を置きたい派です。その際に、神崎氏が懸念しているような 引用部分(blockquote)と出典を直接結びつける方法 を考慮するならば、BLOCKQUOTE要素とCITE要素をひとつのまとまりと見立てるために、更に外側からブロックレベルの要素でラップするというアイデアは悪くないと考えます。正に、神崎氏が同じページで述べている「グループ化Link 」をする訳です。DIV要素を使えば、上記『吾輩は猫である』は以下のように書けるでしょう。

<p>次に、文学作品を引用する。</p>
<div class="quote"> /* 引用に関するセクションのグループ化 */
<blockquote>
 <p>吾輩は猫である。名前はまだない。</p>
</blockquote>
<p><cite>夏目漱石『吾輩は猫である』</cite></p>
</div>          /* グループ化の終わり */
<p>この引用文を読んで、次の設問に答えなさい etc...</p>

 このグループ化の概念をもう少し推し進めて、定義型リストのDL要素Link を用いたグループ化を考えてみます。例えば、上の例は、以下のような感じになります。

/* DL要素を用いたグループ化 その1 */
<dl class="quote">
<dd>
 <blockquote>
  <p>吾輩は猫である。名前はまだない。</p>
 </blockquote>
</dd>
<dt><cite>夏目漱石『吾輩は猫である』</cite></dt>
</dl>

 引用文と、その参照元のセットを、一種の定義型リストと解釈するわけです。定義型リストは、通常は、項目と内容の2つの部分から成り立ち、DT要素に定義する語句を、DD要素にはその語句の説明を記述します。しかしながら、DL要素は、使い方が柔軟で、DD要素あるいはDT要素のいずれか1つ以上を含めばよく、DDとDTの順番は問いません。また、DD要素ひとつに対して、複数のDT要素を含めても良いです。DT要素はインラインレベルの要素のみを含むことが出来て、DD要素は子要素として、ブロックレベルの要素のみを許可します。なので、DD要素の中にBLOCKQUOTE要素が来るのは、何ら問題ありません。上の例では、DT要素がDD要素の後ろに来ていますが、勿論、よく見かけるような形式—DT先行型が好みであれば、以下のような記述になるでしょう。

/* DL要素を用いたグループ化 その2 */
<dl class="quote">
<dt><cite>夏目漱石『吾輩は猫である』</cite>より抜粋</dt>
<dd>
 <blockquote>
  <p>吾輩は猫である。名前はまだない。</p>
 </blockquote>
</dd>
</dl>

 上記例では、引用元は書籍ですが、web上のリソースからの引用であれば、例えば、最初の例を使うと以下のような感じです。読み手に分かりやすいように、DT要素を2箇所で使っています。

<dl class="quote">
<dt>「<cite>いのちの流れ</cite>」より抜粋</dt>
<dd><blockquote
 cite="http://martin.p2b.jp/200812-stream-of-life.html"
 title="生命潮流">
<p>日夜 私の血管を流れる 同じ命の流れが
 この世界を流れ 旋律に合わせて踊る</p>
</blockquote></dd>
<dt class="cite">
 引用元: <a href="http://martin.p2b.jp/200812-stream-of-life.html">
 PPBLOG: 生命潮流
 </a>
</dt>
</dl>

 後は、見栄えを良くするために、これらDL要素などの振る舞いをスタイルシートで指定すればOKです。実際のサンプルは以下。

いのちの流れ」より抜粋

日夜 私の血管を流れる 同じ命の流れが
この世界を流れ 旋律に合わせて踊る

引用元: PPBLOG: 生命潮流 Link

 グループ化している点でHTMLパーサーにも分かりやすく(多分)、また読み手にとっても分かりやすいと思います。また、グループ化のメリットとして、スタイルシートでのデザインが容易くなることが挙げられます。このサイトで使っているBLOCKQUOTEに対するスタイルシートは、以下のようになっています(テーマBasicの場合)。

dl.quote {
  width: 86%;
  background: #fffafa;
  border: solid 1px #aaa;
  margin: 2em auto; padding: 0;
}
dl.quote dt{ padding: 5px 0 0px 10px;}
dl.quote dt cite { font-weight: 600; color: #556b2f; }
blockquote {
  font: 103%/1.7 "メイリオ", "Trebuchet MS", sans-serif;
  color: #484a47;
  margin: 0px auto;
  padding: 15px 15px 15px 48px;
  background: url(Images/quote.png) -5px -5px no-repeat; /* 引用の画像を左上に */
}

 ここでは、BLOCKQUOTE要素の背景に、引用符の画像を固定させていますが、DL要素の背景に、左上の引用符の画像を指定して、BLOCKQUOTE要素の右下にも引用符画像を用意すると以下のような感じになります。

ロマ書 5章3-5節Link より

[...] More than that, we rejoice in our sufferings, knowing that suffering produces endurance, and endurance produces character, and character produces hope, and hope does not disappoint us, [...]

 これに対するスタイルシートは、以下のような感じです。

dl.quote {
  width: 360px;
  background: #fff;
  border: double 4px #2e8b57;
  margin: 2em auto;
}
dl.quote dt {
  padding: 6px 0 0 9px;
}
dl.quote dd {
  background: url(Images/quote-left.png) left top no-repeat;
}
dl.quote blockquote {
  color: #484a47;
  font: italic 105% "Trebuchet MS", sans-serif;
  margin: .7em auto 1em auto;
  padding : 1em 20px 1em 50px;
  background: url(Images/quote-right.png) 97% bottom no-repeat;
}

 この指定では、右下の引用符画像が、BLOCKQUOTEのサイズに応じて、適切な位置に納まるのがポイントでしょうか。これを、グループ化せずに、BLOCKQUOTE要素のみで実現しようとすると、そう簡単には行かないのではないかと思います。[2]

2. CSSによるCITE属性やTITLE属性抽出の問題点

 さて、これまで、BLOCKQUOTE要素とCITE要素のグループ化およびそのメリットについて述べてきました。中には、BLOCKQUOTE要素のCITE属性があるのに、わざわざCITE要素も持ち出して冗長だと感じる方もいるでしょう。しかしながら、前述したように、CITE要素とCITE属性は全く別物です。でも、時々、その中身がほぼ同じという時もあるでしょう。そういう場合は、後述するCSSの指定で、比較的簡単にCITE属性やTITLE属性を抜き出して、読み手に「見せる」ことが可能です。以下に実例を挙げます(IE6,7以外のブラウザでしか意図したように振る舞いません)。

日夜 私の血管を流れる 同じ命の流れが
この世界を流れ 旋律に合わせて踊る

 IE6,7ユーザーの方に、Firefox3.0.5でのスクリーンショットを載せておきます。

Firefox3.0.5-Shot
Firefox3.0.5での見え方

 引用符の画像があって若干見づらいですが、ポイントはそこではなくて、「生命潮流」やら引用元のURIが表示されていることです。IE6,7ユーザー以外の方は、表示されているURL文字列をマウスで選択してみて下さい。このHTMLソースは以下のようです。

<blockquote class="css2compat"
 cite="http://martin.p2b.jp/200812-stream-of-life.html"
 title="生命潮流">
<p>日夜 私の血管を流れる 同じ命の流れが<br />
この世界を流れ 旋律に合わせて踊る</p>
</blockquote>

 BLOCKQUOTE要素のみです。これ以上ないぐらいシンプルですね。これに対するスタイルシートは以下。

blockquote.css2compat {
  background: #f8f8ff;
  border: solid 1px #aaa;
  width: 420px; margin: 2em auto;
  padding: 0 1em 0em 1em;
  font: normal 100%/1.7 'メイリオ';
}
blockquote.css2compat[title]:before {
  content: "¥300C" attr(title) "¥300D¥3088¥308A¥629C¥7C8B";
  display: block;
  padding: 5px;
  margin-left: -1em;
  color: #556b2f;
}
blockquote.css2compat[cite]:after {
  content: "¥5F15¥7528¥5143¥3A¥20" attr(cite);
  display: block;
  font-size: 80%;
  text-align: right;
  color: #777;
  margin-top: 1em;
}

 CSS2.1での:before、:after疑似要素を使って、CITE属性やTITLE属性を抜き出しています。CSS3ならコロン(:)が2つ連続します。モダンなブラウザならダブルコロン(::)でも問題なく作動しますが、IE8βが対応していません(コロン1個なら対応)。なかなか簡単に実装できて便利そうです。しかしながら、問題点が2つあって、ひとつは、ブラウザ最大シェアのIE6,7が未対応なこと。もうひとつは、Operaユーザー以外はそうでしょうが、折角、引用元のURIが表示されているのに、マウスでクリックすることも文字列を選択することも出来ないのです![3] contentの文字列は、文字化けを避けるため、16進数の数値文字参照にしています。多分、日本語のままでも大丈夫でしょうけど。CSSの数値文字変換については、「参考リンク」のセクションにあるサイト(使えない文字)で行いました。

 URIが表示されているのに、それをクリックしてリンクすることも出来ず、それならばと文字列を選択しようにもそれすら出来ない現状では、読み手にやさしい実装とは言えません。何より、IE6,7では全く役に立ちませんし。これならば、JavaScriptで、BLOCKQUOTE要素のCITE属性やTITLE属性を読み出して、リンク表示させた方が読み手には都合が良いでしょう。そういうスクリプトは沢山見つかるでしょうし、ppBlogでも簡単に実装はできます。

 というわけで、この手法はネタとしては魅力的ですが、個人的には、あまりオススメできないかなと思います。

3. 引用ブックマークレットの活用

 そろそろ疲れてきたので、まとめようと思います。読み手にも、(おそらく)解析マシンにも優しい手法として、BLOCKQUOTE要素(+CITE属性)とCITE要素のグループ化が、個人的には、現時点での最適解かなと思います。ただ、このアプローチの弱点は、記述量が増えることです。只のテキストなので、データ量としては大したことはありませんが、ブログなど文章の書き手にとっては、なかなか見過ごせない問題です。そこで、こういうときの引用ブックマークレット。この手の引用ブックマークレットは探せば、いくらでもあると思いますが、自分なりに作成してみました。Firefoxでしか確認してません。他のブラウザ向けに調整が必要かも。

 使い方は、簡単で引用したいwebページの引用箇所を、マウスで選択した状態で、このブックマークレットを発動させると、DL要素でグループ化した状態で、テキストエリアが表示されるので、それをCtrl+Cなどでコピーして「Close」ボタンを押せばOKです。後は、それをブログ作成のテキストエリアなどに貼り付ければ良いわけです。

[quoteIt]

Firefoxなどでは、上記リンクを、ブラウザのリンクバーまでドラッグ&ドロップすれば、そのままブックマークとして登録されます。また、登録しなくても、この記事の適当な部分を選択して上記リンクをクリックすれば、実際にどんな感じか試すことが出来ます。タグを含んだソースなどもコピペ出来るように考慮しています。リンクとかもそのまま有効になるようにしようかなと思いましたが、実際問題としてそこまでの機能は不要かなと思い、それは実装していません。JavaScriptの勉強としては面白そうですが。

4. 参考リンク

 以下、参考になるリンクを挙げておきます。
  • [1] 最も、書籍のISBNが分かっている場合は、有効なURIを示すことも出来ます。
    [参考サイト: URNs, citations in web authoringLink ]
    <blockquote cite="urn:isbn:4-003-10101-4">
    でも、このプロトコルに対応しているブラウザは現時点であまりないと思います。[^]
  • [2] CSS2.1, CSS3のcontentプロパティーを用いて、画像を前後に追加することは出来ますが、如何せんIE6,7が未対応なので、あと数年は実用的ではないかなと思います。[^]
  • [3] 現時点で、手元にあるブラウザで調べたところ、Opera9.63のみが文字列を選択可能で、Firefox3.0.5、Google Chrome1.0.154.36、IE8β、Safari3.2.1では文字列の選択は不可でした。[^]

— posted by martin at 07:54 pm   commentComment [21]  pingTrackBack [0]

T: Y: ALL: Online:
Created in 0.0207 sec.
prev
2009.1
next
        1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31