agenda 2002-11(下旬) 別名「どこか」

fub_net 日記(2)

公開
2002年11月30日

カスタムパネルなどから使用するbookmarkletsでは、表示している文書のdocumentオブジェクトを参照することはできませんでしたが、fub_net(ver. 0.0.1.18)でそれが可能になりました。

HTML版のDOM Inspectorを作ってみました。実際にDOMツリーを視覚化してみると、IE6/WinのDOM1 HTMLの実装の癖や穴が色々見えてきます。TITLE ElementのchildNodes.lengthが0で固定だったり、script要素の終了タグだけが記述されていると、「/SCRIPT」なるElementが存在したり、Elementにユーザー定義のプロパティを追加すると、それがNamedNodeMapにも追加されてAttrとして扱われ、かつspecifiedがtrueになっていたりします:

var elmP = document.getElementsByTagName('P').item(0);
elmP.suicide = function(){
 this.parentNode.removeChild(this);
};

このように、あるP Elementにsuicideというメソッドを定義してやります。すると:

var nnmP = elmP.attributes;
var attrSC = nnmP.getNamedItem('suicide');
alert( attrSC.specified );

結果はtrueです(IE6/Winで確認)。

プロパティを追加してやるということと、setAttribute()してやることは、IE6/Winにとって同じ事のような気がしてなりません。逆にこんなことをしてみました:

var elmP = document.getElementsByTagName('P').item(0);
var f = new Function( "this.parentNode.removeChild(this)" );
elmP.setAttribute('suicide', f);
elmP.suicide();

結果、最初のp要素が消去されます(IE6/Winで確認)。setAttributeメソッドの第二引数は本来文字列ですから、これは不正です。多分。

fub_net 日記

公開
2002年11月23日

しばらくfub_netで遊びます。XSLT、XML Schema、JScript、DOM、fub_netのバグ等々の話題になると思われます。

設定用XMLファイルを利用する(XSLT)

fub_netのメニューに関する情報は、menu.xmlに記述されています。このXMLファイルからキーボードショートカットに関する情報を抽出してHTMLの定義リストを適当に生成するスタイルシートテンプレートを書いてみました。

<xsl:template match="MainMenu">
 <dl>
  <xsl:for-each select="descendant::Menu[@Shortcut and @Text]">
   <dt><xsl:value-of select="@Shortcut" /></dt>
   <dd><xsl:value-of select="@Text" /></dd>
  </xsl:for-each>
 </dl>
</xsl:template>

殆どHTMLの延長です。

さて一方、「プル・スタイル」で書くとこのようになります:

<xsl:template match="MainMenu">
 <dl>
  <xsl:apply-templates select="child::Menu[@Shortcut and @Text]" />
 </dl>
</xsl:template>

<xsl:template match="Menu">
 <xsl:apply-templates select="@Shortcut" />
 <xsl:apply-templates select="@Text" />
 <xsl:apply-templates select="child::Menu[@Shortcut and @Text]" />
</xsl:template>

<xsl:template match="@Shortcut">
 <dt><xsl:value-of select="." /></dt>
</xsl:template>

<xsl:template match="@Text">
 <dd><xsl:value-of select="." /></dd>
</xsl:template>

まるでパラメータエンティティだらけのDTDみたいです。2点。

あまり便利なものとは言えませんが、取り敢えずJPanelsに追加しておきました。JPanelsをfub_net.exeと同じフォルダ内に置いて、shortCutTable.htmlを開きます。

JPanelsを導入済みの場合は、shortCutTable.lzhを解凍して出てきたフォルダの中身を、JPanels内に上書きして下さい。

menu.xmlのスキーマを作る

スキーマ言語はXML Schemaを選びました。MSXMLユーザにはそれしか選択肢がありません(DTDの解析にはバグがある為)。

menu.xmlはシンプルなので取り敢えずは簡単にスキーマを書けますが、問題は柔軟性です。Tag属性の値はfub_net内部で利用されるキーワードらしきものになっており、ユーザーが勝手に変更、追加できないようにする必要があります。ところがこの値は、fub_netの機能拡張に伴って追加される可能性がある為、毎回Tag属性値のデータ型を変更しなければなりません。

スキーマの動的生成

menu.xmlのデフォルトの状態であるmenu.defaultというXML文書を利用し、XMLスキーマにおける列挙型の各データを動的に生成することでこの問題に対処してみます。

具体的には、menu.defaultからTag属性値全てを取得し、スキーマ文書のenumeration要素に変換します。

検証方法

検証対象のXML文書のルート要素にxsi:schemaLocation属性でスキーマ文書のURIを指定していなければなりません(Note:xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance")。

しかし、fub_net側のXMLパーサが何を行っているか私は良く知りません。以前menu.xmlにスタイルシート処理命令を記述したところ、fub_netが起動しなくなりました。menu.xmlに直接スキーマ文書との関連を記述するのは何となく危険な香りがします。

というわけで、次のような手順を踏んでみました。

  1. XSLTで、menu.defaultからTag属性値を抜き出し、それを元にXML Schema文書:fub_menu.xsdを生成、保存
  2. menu.xmlのDOMツリーを操作し、ルート要素にxsi:schemaLocation="fub_menu.xsd"を追加(xsiの名前空間も定義する)
  3. (MSXML4.0で実装された)validateメソッドで変更後の文書(メモリ上に存在)を検証。

面倒です。もっと単純な方法があるかも知れません。

ご挨拶

柔軟性とか偉そうに書いていますが、当然menu.xmlの構造的な変更には対処できません。要するに勝手に遊んでいるだけでして、プレッシャーをかける(謎)意図はありません。

onload.js

fub_netのonload.jsの有り難さに今頃気づきました。これでProxomitronでscript要素を埋め込まずに済みます。

fub_net.exeのあるフォルダにScriptというフォルダを作り、その中にonload.jsという名前で保存します。

不具合

  • ローカルのHTMLファイルを表示している状態で、タブのコンテクストメニューから「タイトルをコピー」を選択すると、title要素ではなく「ファイル名.拡張子」がコピーされる

関係のない追記:namespaceURIぷろぱてぃ

MSXML4.0のヘルプを見ると、namespaceURIプロパティはMSの独自拡張という事になっていますが、仕様書にちゃんとありました。はて? そんなに古かったかな。