&{

スクリプトマクロ (HTML)

スクリプト・マクロ (HTML)

[1] HTMLスクリプト・マクロ (script macro) は、 属性値の中にJavaScriptを埋め込むことができる機能です。

[4] この機能を導入したNetscapeは、 JavaScript実体 (じったい) (entity) あるいは動的実体 (どうてきじったい) (dynamic entity) と呼んでいました。 予約機能として附属書 (参考) にこれを取り込んだHTML 4では、 スクリプト・マクロ (script macro) としています。

[2] 仕様書:

構文

[5]

   attribute = "... &{ macro body }; ... "
のように、属性の中で&{からはじまり、 };で終わる部分がスクリプト・マクロとして解釈されます。 囲まれた部分をHTML 4マクロ本体 (macro body) と呼んでいます。

[6] Netscapeは、文字実体参照文字に展開されるように、 JavaScript実体JavaScript評価結果に展開されるとしています。 1文字目の&&に置き返ると、 JavaScript実体ではなく文字列とみなされます。

SGMLのような属性値属性値指定の区別 (引用符の有無による差異) はない?

[7] 一方でHTML 4Current Practiceをこう説明しています。

  1. まず、SGML構文解析器SGML実体参照展開します。
  2. 次に、スクリプト・マクロマクロ本体スクリプト機関が1つ以上のとして評価します。 スクリプト言語内在事象属性と同じです。
  3. 得られた文字列を以後の処理に使います。

[8] 無理にSGMLとして処理しようとしている点、 マクロ本体ではなくとしている点、 マクロ本体の言語をContent-Script-Typeによって変更可能にしている点がNetscapeの説明と食い違っており、 いったいどこのCurrent Practiceなのかが気になるところです。

特にSGMLとしての処理の部分は、文字実体参照の扱いがNetscapeの実装と大きく異なっており、 HTML 4の通りに処理されるならスクリプト・マクロと同じように見える文字列をHTMLとして記述することができなくなってしまいます。

&{'&{}'+';'};という方法がありますが、 スクリプトが無効だと機能しません。

[10] HTML 4は、スクリプト・マクロが有効なのをCDATA属性のみとしています。 一方Netscapeの説明と実装にはそのような制限は見当たりません。

[11] このスクリプト・マクロ評価される時機について、 Netscape属性値が計算される時としています。 HTML 4は更に明確に、文書が読込まれる時で、再描画の時にはしないとしています。

XSLTとの関係

[18] XSLT 1.0およびXSLT 1.1HTML出力方式では、 属性において&{逃避するべきではないとされています。

HTML 4を見よとは書かれていますが、 閉じ};との対応やCDATA属性か否かのチェックをせよという規定はありません
べき (should) の定義はありません。

[20]

XPath 2.0/XQuery 1.0/XSLT 2.0: 現在の案では、 XSLT 1と同じ、ただしMUST NOT

保安性

[28] 現在のWebアプリケーションなどでは、現存する Webブラウザで依然スクリプト・マクロを実装しているものは無いので、 ユーザー入力などにスクリプト・マクロとして解釈し得る文字列が含まれていてもそのまま出力することが多々あります。 古い利用者エージェントでそのような Webアプリケーションを利用すると XSS の類の攻撃が成功することもあります。

関連

[21] SGMLとの関係: HTML 4ではSGML応用であるためにSGMLとしての属性を更に処理するとしています。 Netscapeが説明・実装している動的実体SGMLに相当するものがなく苦肉の策なのでしょうが、 実装と乖離したものを標準化しようとしても意味がありません。

[24] DOMとの関係: DOMとの関係は明らかではありません。

NetscapeDOM水準0では、評価後の値が使われているものと思われます。 (ただし、Classic Mozillaには文書木そのもののDOM表現が存在していません。)

要確認

[25] W3CDOM仕様には言及がありませんが、 文書の読込み時に評価される (>>11) ことから、 DOM内には評価結果の文字列属性として残ると思われます。

[27] XHTMLとの関係: HTML 4XHTML 1の関係は全体的に不明瞭ですが、 スクリプト・マクロXHTML 1では使えないとする積極的な根拠はありません。

歴史

[22] この機能はNetscape Navigator 3.0β5 で実装されたようです。

[23] HTML 4では標準の機能としては取り込まれませんでしたが、 附属書B (参考) で予約の機能として紹介されています。

HTML 4DTDではWinIEの拡張のdata*属性群が予約として取り込まれているので、 MicrosoftNetscapeの政治的取引の結果かもしれません。

[26] Classic Mozillaに代わるGeckoではスクリプト・マクロは実装されていません。 他のWebブラウザで実装したものも存在しないようです。 HTML 5にもスクリプト・マクロが入ることはないでしょう。 ゾンビが1匹生まれようとしている (>>20) のを除いては、 このまま忘れ去られていくのでしょう。

[9] (JavaScript) Netscape

"&{10 * 10};%"

評価されて100%になります。

[12] 背景色を無作為に選ぶ (JavaScript) HTML 4

<BODY bgcolor='&{randomrgb};'>

既に変数randomrgbに値が入れられているものと思われます。

[13] 背景色を時刻で変化 (JavaScript) HTML 4

<BODY bgcolor='&{if(Date.getHours > 18)...};'>

[14] クライアント側画像写像の範囲とリンク先 (JavaScript) HTML 4

<MAP NAME=foo>
  <AREA shape="rect" coords="&{myrect(imageuri)};" href="&{myuri};" alt="">
</MAP>

[15] 環境依存の画像幅 (JavaScript) HTML 4

<IMG src="bar.gif" width='&{document.banner.width/2};' height='50%' alt="banner">

[16] (JavaScript) HTML 4

 <SCRIPT type="text/javascript">
   function manufacturer(widget) {
       ...
   }
   function location(manufacturer) {
       ...
   }
   function logo(manufacturer) {
       ...
   }
 </SCRIPT>
  <A href='&{location(manufacturer("widget"))};'>widget</A>
  <IMG src='&{logo(manufacturer("widget"))};' alt="logo">

[17] 文字実体参照を含む例 (JavaScript) HTML 4

<IMG src="&{logo(manufacturer(&quot;widget&quot;))};" alt="logo">

[19] XSLTの変換例 XSLT 1.0, 1.1

XSLTスタイル・シート

<BODY bgcolor='&amp;{{randomrbg}};'>
とあるものをHTML出力方式直列化すると、
<BODY bgcolor='&{randomrbg};'>
になります。

メモ

テストが必要:
  • 引用符 ", ', なし
  • &amp;{ };
  • マクロ本体中の文字参照
  • Content-Script-Type
  • 文; 文;
  • 非 CDATA 属性

メモ

[3] XSLT and XQuery Serialization 3.1 () <https://www.w3.org/TR/2017/REC-xslt-xquery-serialization-31-20170321/#HTML_ATTRIBS>