form-associated element

フォーム被関連付け要素、フォーム所有者、form 属性

[1] フォーム被関連付け要素 (form-associated element) は、フォーム所有子を持つことができる要素です >>3フォーム被関連付け要素form 要素と関係を持つことができ、 これを要素フォーム所有子 (form owner) といいます >>24

[71] フォーム所有子木構造に基づき自動的に決まりますが、 form 内容属性によって著者が上書きすることもできます。どの要素フォーム所有子であるかは form IDL属性によって取得できます。

仕様書

分類

[124] フォーム被関連付け可能要素には次のような小分類があります。

[138] ただしラベル付け可能要素には、フォーム被関連付け可能要素でないものも含まれています。

フォーム被関連付け要素の一覧

[15] option, optgroup, legend, datalist は含まれていません。

[132] object は理論上はフォーム制御子として使えるため、ここに含まれています。

[133] img は歴史的経緯から document.forms[n].imgname のようにアクセスできるため、 内部的にフォームとの関連付けを保持しており、ここに含まれています。

[137] meterprogress>>136 により一時的に含まれていました。

[8] かつては label も含まれていました。

[139] これらはいずれも字句内容フロー内容として使うことができる要素です。

再関連付け可能要素

[125] 再関連付け可能要素 (reassociateable element) は、 form 内容属性form IDL属性を有するフォーム所有子を指定可能なフォーム被関連付け要素です。

[9] label から form 内容属性が削除されたことで、被列挙要素と同じとなり、廃止されました。

一覧

[127] 各分類に属する要素の一覧は >>126 にあります。

状態

[64] フォーム被関連付け要素は、次の状態を持ちます。

フォーム所有子
>>72
構文解析器挿入フラグ
構文解析器による挿入かどうかを表します。 フォーム所有子の再設定に関わります。

フォーム所有子

[72] フォーム被関連付け要素は、フォーム所有子 (form owner) を持ちます。 フォーム所有子は、 form 要素または null です >>24

[65] フォーム所有子は、原則として次のように決まります。

影を含む文書中にない
null
form 属性がある
参照されている form 要素
form 要素祖先にある
祖先form 要素
それ以外
null

フォーム所有子の変化

[108] フォーム所有者は次の場合に変化します。

[28] フォームとの関連付け自体は影木にも適用されますが、 form 属性による関連付けは同じでなければなりません。
[95] 構文解析器によってフォーム被関連付け要素作成され、 挿入される場合、作成時点でフォーム関連付けが行われ、 挿入時の通常のフォーム所有者の再設定は行われません >>94構文解析器挿入フラグはこの挙動の管理に使われています。

フォーム所有者の再設定

[85] フォーム被関連付け要素要素フォーム所有者の再設定 (reset the form owner) は、 次のようにしなければなりません >>24

  1. [66]
    ... のすべてを満たすなら、
    1. [33] ここで停止します。
  2. [35] 要素フォーム所有者を、 null に設定します。
  3. [34]
    ... のすべてを満たすなら、
    1. [39] フォームを、
      ... のすべてを満たす、木順で最初の要素に設定します。
    2. [58] フォームform 要素なら、
      1. [59] 要素フォームフォーム関連付けします。
  4. [60] それ以外で、要素祖先form 要素があれば、
    1. [63] フォームを、要素祖先で直近の form 要素に設定します。
    2. [62] 要素フォームフォーム関連付けします。

[93]

...
 <form id="a">
  <div id="b"></div>
 </form>
 <script>
  document.getElementById('b').innerHTML =
     '<table><tr><td><form id="c"><input id="d"></table>' +
     '<input id="e">';
 </script>
...

e 要素フォーム所有子c ではなく a になります >>24

innerHTML が内部的にHTML構文解析器で解釈を終えた時点では、確かに eフォーム所有者c です (form 要素が閉じられていませんから)。ところが e 要素b 要素子供となった瞬間に、フォーム所有者の再設定が起こり、 a に選び直されます。

form 要素指示子

[96] HTML構文解析器form 要素指示子 (element pointer) は、 最後に開かれて閉じていない form 要素を指すものです >>98

仕様書

省略可能性

[147] form要素指示子は、スクリプト無効構文解析器でも実装する必要があります。 (値によって構文解析の結果が変化します。) しかしフォーム所有者の再設定の呼び出しは、 スクリプトフォームを実装していないなら、省略できます。

値の変化

[105] つまり、開始タグがあって終了タグが(まだ)ない最後の form 要素を指している状態になっています。

[141] form 終了タグは、たとえそれによって閉じられる form 要素が存在していなくても、 form要素指示子null に設定する効果があります。 table などをトリッキーに使って、あるいは素片構文解析によってそのような状況が生じることがあります。

[142] ただし、素片構文解析の場合は、一時的に架空のにおいて構文解析を行った後、 得られた節点が指定された位置に挿入される、という形を取っており、 最終的な挿入は構文解析器による挿入ではありませんから、 たとえform要素指示子により特別なフォーム所有者の関連付けが行われていたとしても、 再設定により失われてしまいます。

[143] <http://software.hixie.ch/utilities/js/live-dom-viewer/?%3Cform%20id%3Da%3E%0A%3Cscript%3E%0A%20%20document.forms%5B0%5D.innerHTML%20%3D%20%27%3C%2Fform%3E%3Ctable%3E%3Cform%20id%3Db%3E%3Ctr%3E%3Ctd%3E%3Cinput%3E%27%3B%0A%20%20w%20(document.getElementsByTagName%20(%27input%27)%5B0%5D.form.id)%3B%0A%3C%2Fscript%3E> の例では、 form 要素innerHTML を設定しています。その場合form要素指示子が設定されてから構文解析がはじまるので、 form 開始タグは無視されます。ところが本例では form 終了タグによってform要素指示子null に設定されるため、 form 開始タグは無視されず、 form 要素が作られます。

[144] ただし form 要素里親付けにより table 要素となり、 td 要素内の input 要素はその form 要素子孫とはなりません。 それでもform要素指示子によって両者は一旦関連付けられるのですが、 素片構文解析の全体が完了した後、得られた要素が1つ目の form 要素子供として挿入され、フォーム所有者の再設定が実行されます。 この時に木構造に従いフォーム所有者が決定されるので、 input 要素フォーム所有者は変更されるのです。

[145] なお、先祖に form 要素が存在するケースの素片構文解析では、 form要素指示子構文解析中に変更されない場合、 構文解析の時点ではフォーム所有者は設定されず、 最後の挿入の時点で木構造に従いフォーム所有者が決まることになります。

フォーム所有者構文解析によって作成された要素が同じ家部分木に属さないからです。 字句から要素の作成の項を参照。

構文解析への影響

[106] form要素指示子form 要素を指している間は HTML構文解析器form 要素を新たに作ることはありません。 つまり、 form 要素の入れ子状態を HTML構文解析器自身が作り出すことはありません。

[119] template 要素内ではform要素指示子は無視され、 フォーム制御子フォームの関連付けは行われません。

[146] 構文解析器AAA によって要素を移動した場合、 構文解析器による挿入としてではなく、 通常の insert として処理されるため、 結果的にform要素指示子は無視されます。

関連

[107] form要素指示子は、HTML構文解析器によってフォーム被関連付け要素文書に挿入される時点でフォーム所有者の決定に使われます (>>95)。

[109] フォーム所有者の再設定が起こる (>>108) と form要素指示子の影響で生じたフォームとの関連付けは解消されます。 従ってform要素指示子の影響は構文解析の直後に限定されます (といっても構文解析innerHTML などでいつでも発生し得ます)form要素指示子がなかった場合との違いが生じるのは、 form 要素終了タグ無しで閉じられた後に続くフォーム制御子が、 form 要素子孫でもないのに関連付けられる場合だけです。

[110] HTML素片構文解析算法の中で form 要素が閉じられると、 その文脈節点先祖である form 要素子孫であるにも関わらず関連付けられるフォーム制御子が発生しそうに思えますが、 そのような状況で form 要素を開くことがそもそもできないはずです。

form 属性 (HTML)

以下は古い内容が含まれます。

[40] HTMLフォーム制御子等の form 属性は、 フォーム制御子が所属するフォームを指定します。

[41]

状態
WHATWG WD
要素型
フォーム制御子fieldset
属性名
form (form (フォーム) より)
属性値
IDREFS (>>42)
既定値
(先祖により決定) (>>43)

仕様書

属性値

[79] form 内容属性属性値は、同じ文書form 要素ID でなければなりません >>77

[42] Web Forms 2.0 では、 form 属性値は、 零個以上の form 要素ID空白区切り並びとされていました WF2 2.8

フォームの決定

[49] 利用者エージェントは、フォーム制御子fieldset 要素に関連付けるフォームを次のように決定しなければなりません WF2 2.8:

  1. form 属性があれば、 それに従います。
  2. 直近先祖である form 要素か、 form 属性がある fieldset 要素があれば、 そのフォームとします。
  3. なければ、どのフォームにも関連付けないとします。

フォーム操作との関係

[50] 提出ボタン (submit) や画像 (image) は、 関連付けられた最初のフォームのみを提出しなければなりませんWF2 2.8

[51] 再設定ボタン (reset) は、関連付けられたすべてのフォーム再設定しなければなりませんWF2 2.8

誤り処理

[52] 文書中に複数現れる IDform に指定された時に選択されるフォームは、 getElementById メソッドと同じものとしなければなりませんWF2 2.8

getElementById メソッドは、 その場合の動作は未定義としています。 しかし、 form もそれと同じように動作しなければならない、ということです。

[53] form 属性値中に同じフォームを複数回指定してはなりません利用者エージェントは、その場合、 最初の指定を除き、無視しなければなりませんWF2 2.8

[54]

<table>
 <thead>
  <tr>
   <th>Name</th>
   <th>Value</th>
   <th>Action</th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <td>
    <form id="edit1" action="/edit" method="post">
     <input type="hidden" name="id" value="1"/>
     <input type="text" name="name" value="First Row"/>
    </form>
   </td>
   <td>
    <input form="edit1" type="text" name="value"/>
   </td>
   <td>
    <input form="edit1" type="submit" name="Edit"/>
   </td>
  </tr>
  <tr>
   <td>
    <form id="edit2" action="/edit" method="post">
     <input type="hidden" name="id" value="2"/>
     <input type="text" name="name" value="Second Row"/>
    </form>
   </td>
   <td>
    <input form="edit2" type="text" name="value"/>
   </td>
   <td>
    <input form="edit2" type="submit" name="Edit"/>
   </td>
  </tr>
 </tbody>
</table>

ごとに別のフォームになっています。 WF2 2.8 [tbody]] の内容モデルの定義から、 Web Forms 1.0 ではこのようにフォームを組合せることができませんでした。

[55]

<form action="test.cgi">
 <input type="text" name="q" form="fg fy">
 <input type="submit" name="t" value="Test">
</form>
<form id="fg" action="google.cgi"><input type="submit" value="Google"></form>
<form id="fy" action="yahoo.cgi"><input type="submit" value="Yahoo"></form>

テキスト欄は2つのフォームに関連付けられています。 また、フォームが3つあり、それぞれが提出ボタンを持っています。 WF2 2.8

GoogleYahoo の2つのボタンは、 それぞれ別のフォーム処理エージェントに、 同じテキスト欄の内容を提出します。

最初の Test は、 Web Forms 2.0 に適合した利用者エージェントでは、 テキスト欄の内容を提出しません。 未対応の利用者エージェントはテキスト欄の内容を提出します。 これは古い利用者エージェントのための fallback として使うことができます。

歴史

[128] >>61 では後の form 属性に相当する for 属性が提案されていました。

Web Forms 2.0

[44] form 属性Web Forms 2.0 で導入されました。

処理モデル

[43] フォーム制御子は通常先祖form と関連付けられますが、 form 属性はこれを上書きし、 関連付けるフォームを明示的に指定します。 WF2 2.8

[46] 指定された ID のうち、 文書中の要素識別しないものや、 form 要素識別しないものは、 無視しなければなりませんWF2 2.8

[47] 空文字列属性値として指定する (か、 >>46 の無視の結果 ID が1つも含まれない) と、 フォーム制御子はどのフォームにも関連付けられていない状態となります。 WF2 2.8

[48] fieldset 要素に指定した場合は、 その子孫フォーム制御子を関連付けるフォームを指定します。 WF2 2.8

子孫フォーム制御子fieldset で更に form が指定されている場合は、 そちらが優先します。

HTML5

[129] WF2 はその後 HTML5 (旧 Web Applications 1.0、現在の HTML Standard) に統合されました。

[70] 一瞬だけ HTML5legend 要素にも form 属性が追加されていましたが、すぐに削除されました。

[136] meterprogressフォーム被関連付け可能要素の一部であるラベル付け可能要素とするために >>134form 属性が追加されましたが、 >>135ラベル付け可能要素フォーム被関連付け可能要素でなくても良いこととされ、 form 属性も削除されました。

[130] HTML5 ではフォーム所有者の概念の詳細や構文解析との相互関係が歴史上はじめて明文化されました。

[140] HTML Speech Incubator Group Final Report ( ( 版)) <http://www.w3.org/2005/Incubator/htmlspeech/XGR-htmlspeech-20111206/#dfn-form>

[16] 13549 – 4.10.18 associating form elements with forms that do not contain them can cause navigation problems for AT and keyboard users ( 版) <https://www.w3.org/Bugs/Public/show_bug.cgi?id=13549>

[25] Editorial: synchronize with the DOM Standard · whatwg/html@21c6ec7 ( 版) <https://github.com/whatwg/html/commit/21c6ec77594eb89b836d4872222f5916910967fd>

[26] Remove <label form> and redefine label.form IDL attribute ( (zcorpan著, )) <https://github.com/whatwg/html/commit/99f0f1ae017523276ea4dd5784ec63a23a23834d>

[27] Web Forms 2.0 ( ()) <https://whatwg.org/specs/web-forms/current-work/#formAttribute>

[12] Make forms work in shadow trees ( (annevk著, )) <https://github.com/whatwg/html/commit/927fda0f305452a9c54a25d3ebf9a6ed5ae29fd3>

[68] Clarify label.form IDL attribute ( (zcorpan著, )) <https://github.com/whatwg/html/commit/7894cba1f9f46064969f8e0f46a90e3c8d4dbad5>

[69] Be more precise about nested and discarded browsing contexts (domenic著, ) <https://github.com/whatwg/html/commit/39118df640ad4a3f03f164fb5ffe0a56316297be>

[73] Remove <keygen> (domenic著, ) <https://github.com/whatwg/html/commit/5baa38720f6e83c94a50018c4565808ad548d69c>

[74] Track HTML parser form-associated elements with a flag (annevk著, ) <https://github.com/whatwg/html/commit/384c30c56d6dfd26dfbd3a5024ae10e7f7134483>

[29] 28800 – Should 'reset form owner' be invoked on form-associated elements with no form owner when they are inserted into a subtree that is NOT IN the Document? () <https://www.w3.org/Bugs/Public/show_bug.cgi?id=28800>

[67] "reset the form owner" is not quite right · Issue #2863 · whatwg/html () <https://github.com/whatwg/html/issues/2863>

[86] Track HTML parser form-associated elements with a flag by annevk · Pull Request #2874 · whatwg/html () <https://github.com/whatwg/html/pull/2874>

[90] Add the autocapitalize attribute (rlanday著, ) <https://github.com/whatwg/html/commit/f1f0af83e320f14a59dc4e552ee82aab7908f00c>

[91] Drop IMG element from form-associated elements · Issue #294 · whatwg/html () <https://github.com/whatwg/html/issues/294>