次のHTML文書の断片をDOM APIを利用して生成してみます:
<div class="container" id="foo">
<h2>だいあろぐ</h2>
<label>
<input type="button" onclick="alert(true)" />
</label>
</div>
実際にやってみると次のようになります(一例)。
var div = document.createElement('DIV');
var h2 = document.createElement('H2');
h2.appendChild(document.createTextNode('だいあろぐ'));
div.appendChild(h2);
var label = document.createElement('LABEL');
var input = document.createElement('INPUT');
input.type = 'button';
input.addEventListener('click', function(){alert(true)}, true);
label.appendChild(input);
div.appendChild(label);
この面倒くささ、視認性の悪さを何とかしようというのが主な動機です。尚、addEventListnerの部分はブラウザによっては別の方法にしなければなりません。そして、そういったブラウザ毎の差異を吸収する目的もあります。上記のコードは生成過程であって、HTMLの実体を表すものではありません。従って、生成過程が対応ブラウザ等々によって異り、それぞれに対応する場合、コードから実体を読み取ることは非常に困難になります。
var br = { br: null }; // (1)
br要素を、JavaScriptのオブジェクトリテラル{ key: 値 }で抽象的に表現しています(js-html)。key が要素名、値がその内容です。空要素の場合はnullです。
href属性を持ったa要素(<a href="http://example.com" title="example.com">example.com</a>)は次のように表現します。
var a = {
a: "example.com", // (1)
$attrs: { href: "http://example.com", title: "example.com" } // (2)
};
class属性だけは、$attr: {"class": "date"} のように、クォーテーションで括る必要があります。JavaScriptの予約語「class」と衝突する為です。
<div><h1>spam</h1></div>:
var div = {div: {h1: "spam"} };
li要素を二つ持ったul要素は次のように表記できます。
var ul = {
ul:
[
{ li: "item1" },
{ li: "item2" }
]
};
bulider.feed(ul);
builder.build();
ある要素ulに複数の子要素liがある場合、ul key の値は配列になり、配列のアイテムとして、同様に抽象化したliを列挙します。
<p>きみの論文は<em>危険</em>だよ、ロージャ。</p>を表現してみます。
var p = {
p:
[
"きみの論文は",
{ em: "危険" },
"だよ、ロージャ。"
]
}
イベントハンドラは属性として扱い、値に関数オブジェクトを指定します。
var button = {
button: "私は何者",
$attrs: { onclick: function(){alert(this.nodeName);} }
}
コメントと処理命令は、特別なkey、$comment、$pi を使います。
var comment = { $comment: "コメントです。" }
var pi = { $pi: "target content" }
というか$piは使わないでしょう。
PrimalNode ::= ElementExpr | CommentExpr | PIExpr
ElementExpr ::= '{' ElmentName ':' ElementValue (',' AttrSet)? '}'
ElementValue ::= Children | Node
Node ::= PrimalNode | String
Children ::= '[' Node (',' Node)* ']'
AttrSet ::= '$attrs' ':' '{' AttrExpr (',' AttrExpr)* '}'
AttrExpr ::= AttrName ':' ( String | Function )
CommentExpr ::= '{' '$comment' ':' String '}'
PIExpr ::= '{' '$pi' :' String }'
ElementName は要素名、AttrNameは属性名です。それぞれHTMLの仕様に準じます。
Stringは、JavaScriptの任意のStringオブジェクトです。内容の制限はHTMLの文法に準じます。
FunctionはJavaScriptの任意の関数オブジェクトです。これはonclick属性等のイベントハンドラにのみ適用されます。
HTMLBuilderで js-html を具体的なHTMLに変換できます。