Ray Ozzie 氏の提案する Live Clipboard 、どのような仕組みになっているか気になっていたので調べてみた。まずその前に Live Clipboard の簡単なデモを作ってみた。
Live Clipboard Demo
それでは、まず UI の仕組みから調べていこう。右クリックした時にでてくるメニューは TEXTAREA のものだ。意外に思うかも知れないが、CSS で cursor を pointer にして、z-index をプラスにして、Opacity を 0 にしてある。そして右クリックの MouseDown のイベント(メニューがでる直前)でその TEXTAREA のテキストをクリップボードにコピーしたい内容に置き換えて、Select All をする。その後すぐにメニューが表示されるので、あとはユーザーがコピーを選択すればテキストがクリップボードへコピーされるという訳だ。それでは Paste はどうかというと、onPaste というイベントはないのでなんとタイマーを使って毎0.05秒ごとに TEXTAREA のテキストが変わっていないかをチェックしている。もしカットやペーストされればテキストが変わるので、それが onPaint ということだ。うーん、どう考えても Hack としか思えないようなテクニックだが、クロスプラットフォームとセキュリティーを実現するには他にあまり方法はないのかも知れない。
さて、次にクリップボードに実際にコピーされるデータの形式について。これは XML で、親切にきちんと Document してあるのでそちらを参照してもらいたい。参考に vCard の XML はこんな感じ:
<?xml version="1.0" encoding="utf-8" ?>
<liveclipboard version="0.92"
source="http://localhost:2475/live/liveclipboard.htm"
xmlns:lc="http://www.microsoft.com/schemas/liveclipboard">
<lc:data>
<lc:format type="vcard" contenttype="application/xhtml+xml">
<lc:item>
<div class="vcard uid" title="undefined">
<div class="fn n"><span class="given-name">Keiji</span> <span class="family-name">Oenoki</span></div>
<a class="email" href="mailto:keijio@microsoft.com">keijio@microsoft.com</a>
<div class="tel"><span class="value">425-705-0742</span></div>
<div class="adr">
<span class="type">Work</span>:
<div class="street-address">1065 La Avenida St</div>
<span class="locality">Mountain View</span>
<span class="region">CA</span>
<span class="postal-code">94043</span>
<span class="country-name">USA</span></div></div>
</lc:item>
</lc:format>
</lc:data>
</liveclipboard>
ここで重要なのはマイクロフォーマットが利用されているという事。マイクロフォーマットは簡単に言えば HTML に CSS のクラス名を使って情報を付け足すという面白いテクニック。例えば名前なら
<p>This document was prepared by <span class="name">Keiji Oenoki</span>,
who lives in Mountain View...</p>
という具合だ。人にもコンピュータにも読みやすくするのがマイクロフォーマットの目的だ。ペーストの時にはこの XML を Parse して、必要な情報を手に入れるという仕組み。
次に、プレゼンテーションのための CSS 。これでどの情報をどのように見せるか調節する。例えば名前を Bold にしたり、アドレスを見せないようにしたりできる。
最後に、JavaScript がデータとプレゼンテーションを繋げる。Live Clipboard では HCard、 MicroFormatBindingObject、WebClip の3つのオブジェクトを使っている。
var hCard1 = new HCard("Keiji", "Oenoki", "keijio@microsoft.com",
"425-705-0742", null, null, null, null, null, null,
null, null, null, null, null, null, null, null,
"1065 La Avenida St", "Mountain View", "CA", "94043","USA", "Microsoft");
var contactBinding1 = new MicroFormatObjectBinding(
document.getElementById("contactHcard1"),
hCard1, "ContactContainer unselected",
"ContactContainer selected");
var clipBoardControl1 = new WebClip(
document.getElementById("webClipControl1"), contactBinding1.onCopy,
contactBinding1.onPaste, contactBinding1.onActive, contactBinding1.onInactive);
一行目で hCard データそのものを作り(データ)、二行目でその hCard を DIV とくっつけて見れるようにし(プレゼンテーション)、そして三行目でイベントを使ってデータとプレゼンテーションを連動させる。(ちなみに最初に話した TEXTAREA は WebClip に渡された DIV に作られる。) WebClip のイベントは四つある。
- onCopy コピーに使われるデータを渡す
- onPaste ペーストだけでなくカットや Delete でも呼ばれる
- onActive セレクトされた時
- onInactive セレクトが終わった時
これで完成。ソースコードを公開しているので、興味のある方はこちらから。