adopting step

養子化 (DOM)

[12] DOM において養子化 (adopt) とは、ある節点節点文書 (ownerDocument) をある文書に書き換える操作です。 この時節点がいればその親子関係は解消され、 節点子節点その他付随する節点があればそれらの節点文書も新しい節点文書に書き換わります。

[13] Document オブジェクトadoptNode メソッドは、指定された節点を当該 Documentadopt します。

[14] adopt 操作は adoptNode メソッド以外でも用いられます。 例えば adoptChild は新しい子節点親節点と同じ文書に移し、 既にがいればその親子関係を解消するために adopt します。

仕様書

養子化操作

[46] 養子化では、次のような操作が行われます。

[50] 「★」のあるものは、当該節点のみに適用されます。 それ以外は、子孫雛形内容および影木にも適用されます。

[15] ある節点節点のある文書新文書への養子化 (adopt) 操作は、 次の処理で構成されます >>10

  1. [38] 旧文書を、節点節点文書に設定します。
  2. [41] 節点null 以外なら、
    1. [16] 節点から節点削除します。
  3. [43] 旧文書新文書が異なるなら、
    1. [40] 節点影を含む包括的子孫の各節点文書を、新文書に設定します。
    2. [54] 節点影を含む包括的子孫の各要素属性リストの各属性節点文書を、新文書に設定します。
    3. [36] 節点影を含む包括的子孫の各要素要素について、
      1. [44] 要素カスタムなら、
        1. [45] 要素カスタム要素コールバック反応をキューに追加します。 コールバック名adoptedCallback, 引数リスト旧文書新文書リストとします。
    4. [17] 節点影を含む包括的子孫の各節点について、 影を含む木順に、
      1. [18] 節点旧文書に関する養子化手順群を実行します。

[19] 養子化手順群 (adoption steps) >>10 には、次のものがあります。

[27] >>9adopting steps が導入される以前に規定されたため、>>33 まで 「ownerDocumentが変化した時」という表現になっていました。 adopt はそれ以外でも発生しますが、実質的には同じでした。

[28] >>32 以前の DOM Standardadopt された節点 () に対して adopting steps を呼ぶと言っていますが、 HTML Standard は変更が発生した節点すべてに対して adopting steps が呼ばれることを期待していて、齟齬がありました。

[3] >>16削除操作内で removing steps も実行されます。

[78] 養子化は、その節点だけでなく子孫にまで影響が及びます。 影木があれば、そちらにも影響が及びます。

[79] 養子化の時点でがあれば、削除 (親子関係が解消) されます。 従って養子化の影響は (削除を除き) 祖先には及びません。

[76] DocumentFragmentホストを持つ場合には、 同時にのみ養子化されることになっています。

[55] 影根adoptNode (>>72) や importNode に引き渡すと、 例外投げることになっています。その他養子化が呼び出される場面では、 影根が(単独で)養子化されることはありません。

[77] よって影根は常に影ホストと同じ文書に属します。

[80] 養子化は、

から呼び出されます。

Document インターフェイス adoptNode メソッド (DOM)

[20] Document オブジェクトadoptNode メソッドは、 指定した節点をその文書へと養子化します。 >>11

[21] 具体的には、次のようにしなければなりません >>11

  1. [63] 文書を、文脈オブジェクトに設定します。
  2. [64] 節点を、第1引数を Node として解釈した結果に設定します。
  3. [22] CEReactions:
    1. [62] 節点節点型文書の場合、
      1. [65] NotSupportedError DOMException投げ、 ここで停止します。
    2. [66] 節点影根の場合、
      1. [67] HierarchyRequestError DOMException投げ、 ここで停止します。
    3. [68] 節点DocumentFragment で、 節点ホストnullない場合、
      1. [69] 節点を返し 仕様書になし、 ここで停止します。
    4. [70] 節点文書養子化します。
    5. [71] 節点を返します。

[72] つまり引数節点養子化するのですが、 DocumentFragment のとき特殊な挙動になります。 DocumentFragment は3種類ありますが、そのうち2種類はホストがあります。 ホストがある DocumentFragment は、 ホストと同時にのみ養子化できます >>58 (>>76)。 例外を返したり何もしなかったりするのは、後方互換性のためとされます >>58。 この処理はの改正で明文化されました >>56 が、 それ以前の Webブラウザーの処理は曖昧でした。

[73] そのときの修正ミスで何も返さないケースが生じていますが (>>69)、 Chrome では常に節点が返されるようです。

[74] このメソッドは常に引数をそのまま返します。つまりあまり意味はありません。 chaining の便宜とも思われますが、 DOM にはそういうのはあまりないので、 どうなのでしょう。 (appendChild に近いパターンなので、やはりそうなのかもしれませんが。)

[75] DOM3文書が異なるDOM実装に属することも想定しているので、 もしかすると引数返値が違うケースがあったのかもしれません。 しかし DOM3 はそのへんのアーキテクチャーをあまりはっきり語っていなかったので、 その場合に引数節点オブジェクトはその後どうなってしまうのかなど、 謎が多いです。

[23] adoptNode メソッドは、 DOM3 で追加されたものでした。 DOM3 仕様上は明示的に adoptNode を呼ばなければ adoptChild などで違う文書に挿入することができませんでした。

[61] しかし現実の Webブラウザーは当時から自動的に adopt する実装にほぼなっていました。 現在の DOM Standard はそちらの動作を採用しているため、 このメソッドが必要になる場面はほとんどありません。

歴史

[1] [dom3core] Cross-document appending of nodes from Anne van Kesteren on 2006-08-24 (www-dom@w3.org from July to September 2006) http://lists.w3.org/Archives/Public/www-dom/2006JulSep/0012 (名無しさん 2006-09-10 04:25:33 +00:00)

[2] 原始文書対象文書が同じ場合に UserDataHandler があれば呼ばれるのかどうか、 メソッドの返す値は何かは明記されていません。

[4] UserDataHandler が呼ばれるタイミングは明記されていません。 (複数の節点が同時に養子縁組されるとき、 すべての節点養子縁組し終えてから呼ばれるのか? どの順番で呼ばれるのか?) (名無しさん)

[5] DocumentDocumentType養子縁組しようとすると NOT_SUPPORTED_ERR ですが、 EntityNotation だとどうなるのかは不明です。

[6] Re: [dom] Need to describe the interaction of adoptNode with prototype chains ( (Boris Zbarsky 著, 版)) http://lists.w3.org/Archives/Public/www-dom/2013JanMar/0075.html

[7] Web Applications 1.0 r8270 Share the ownerDocument of template contents amongst the templates of a document. ( ( 版)) http://html5.org/tools/web-apps-tracker?from=8269&to=8270

[8] Index of /~stewart/css/html-options ( 版) http://www.metahusky.net/~stewart/css/html-options/

[31] adopting steps要素の基底URLの処理の一般化として >>29 で導入されました。

[34] Make two loops to adopt a node · whatwg/dom@718ba4a ( 版) https://github.com/whatwg/dom/commit/718ba4aeade05a08e8fafee18cf2fb07e7e7f806

[35] Fix #146: only run adopting steps when changing documents · whatwg/dom@bb69d0b ( 版) https://github.com/whatwg/dom/commit/bb69d0b0b280bf283550f2c21cabd0e6aa1d4cfc

[37] Add [CEReactions] annotations to mutating methods · whatwg/dom@3cd02d1 ( 版) https://github.com/whatwg/dom/commit/3cd02d139c159a31fbb400e03932652c72fc7812

[39] Un-customify adopted elements ( (domenic著, )) https://github.com/whatwg/dom/commit/e417f9f4ca5aa16f11b8e04378f8c3425554b0fd

[42] Set the stage for new custom element adoption semantics (domenic著, ) https://github.com/whatwg/dom/commit/674e9343c811b178b5d1821e469682df0aa616f9

[52] Pass the old and new document to adoptedCallback (domenic著, ) https://github.com/whatwg/dom/commit/026a77291fe09f3d4880775e03bbb875fd90f833

[53] Make Attr inherit from Node again (annevk著, ) https://github.com/whatwg/dom/commit/625a0747f137454c155a7b577a9e45be1aa35a34

[60] >>56 DocumentFragment の扱いが修正されました。