[12] [[DOM]] において[DFN[[RUBYB[[[養子化]]]@en[adopt]]]]とは、ある[[節点]]の[[節点文書]]
([CODE(DOMa)@en[[[ownerDocument]]]]) をある[[文書]]に書き換える操作です。
この時[[節点]]の[[親]]がいればその[[親子]]関係は解消され、
[[節点]]の[[子節点]]その他付随する[[節点]]があればそれらの[[節点文書]]も新しい[[節点文書]]に書き換わります。

[13] [CODE(DOMi)@en[[[Document]]]] [[オブジェクト]]の [DFN[[CODE(DOMm)@en[[[adoptNode]]]]]]
[[メソッド]]は、指定された[[節点]]を当該 [CODE(DOMi)@en[[[Document]]]] に [[adopt]] します。

;; [14] [[adopt]] 操作は [CODE(DOMm)@en[[[adoptNode]]]] [[メソッド]]以外でも用いられます。
例えば [CODE(DOMm)@en[[[adoptChild]]]]  は新しい[[子節点]]を[[親節点]]と同じ[[文書]]に移し、
既に[[親]]がいればその[[親子]]関係を解消するために [[adopt]] します。

* 仕様書

[REFS[
- '''[10] [CITE@en-US[DOM Standard]] ([TIME[2014-03-20 17:08:41 +09:00]] 版) <https://dom.spec.whatwg.org/#concept-node-adopt>'''
- [11] [CITE@en-US[DOM Standard]] ([TIME[2014-03-20 17:08:41 +09:00]] 版) <https://dom.spec.whatwg.org/#dom-document-adoptnode>
- [24] [CITE@en-US-x-hixie[HTML Standard]] ([TIME[2014-04-03 03:44:44 +09:00]] 版) <http://www.whatwg.org/specs/web-apps/current-work/#the-img-element>
- [26] [CITE@en-US-x-hixie[HTML Standard]] ([TIME[2014-04-03 03:44:44 +09:00]] 版) <http://www.whatwg.org/specs/web-apps/current-work/#the-template-element>
]REFS]

* 養子化操作

[46] [[養子化]]では、次のような操作が行われます。
[FIG(list)[
- [47] [F[親][parentNode]]の消去 ★
- [48] [F[節点文書]]の書き換え
- [49] [CODE(HTMLe)@en[img]] [[要素]]の読み込み
- [51] [[カスタム要素コールバック反応]] [DFN[[CODE[adoptedCallback]]]] の実行
]FIG]

[50] 「★」のあるものは、当該[[節点]]のみに適用されます。
それ以外は、[[子孫]]、[[雛形内容]]および[[影木]]にも適用されます。

[15] ある[[節点]][VAR[節点]]のある[[文書]][VAR[新文書]]への[RUBYB[養子化]@en[adopt]]操作は、
次の処理で構成されます [SRC[>>10]]。
[FIG(steps)[
= [38] [VAR[旧文書]]を、[VAR[節点]]の[F[節点文書]]に設定します。
= [41] [VAR[節点]]の[F[親][parentNode]]が [[null]] 以外なら、
== [16] [VAR[節点]]の[F[親][parentNode]]から[VAR[節点]]を[[削除][removeChild]]します。
= [43] [VAR[旧文書]]と[VAR[新文書]]が異なるなら、
== [40] [VAR[節点]]の[[影を含む包括的子孫]]の各[F[節点文書]]を、[VAR[新文書]]に設定します。
== [54] [VAR[節点]]の[[影を含む包括的子孫]]の各[[要素]]の[F[属性リスト]]の各[[属性]]の[F[節点文書]]を、[VAR[新文書]]に設定します。
== [36] [VAR[節点]]の[[影を含む包括的子孫]]の各[[要素]][VAR[要素]]について、
=== [44] [VAR[要素]]が[F[カスタム]]なら、
==== [45] [VAR[要素]]を[[カスタム要素コールバック反応をキューに追加]]します。
[VAR[コールバック名]]は [CODE[adoptedCallback]], 
[VAR[引数リスト]]は[VAR[旧文書]]と[VAR[新文書]]の[[リスト]]とします。
== [17] [VAR[節点]]の[[影を含む包括的子孫]]の各[VAR[節点]]について、
[[影を含む木順]]に、
=== [18] [VAR[節点]]と[VAR[旧文書]]に関する[[養子化手順群]]を実行します。
]FIG]

[19] [DFN[[RUBYB[養子化手順群]@en[adoption steps]]]] [SRC[>>10]] には、次のものがあります。
[FIG(list)[
- [25] [CODE(HTMLe)@en[[[img]]]] [[要素]]では、 [[update the image data]] やそれに相当する処理 [SRC[>>24]]
- [9] [CODE(HTMLe)@en[[[template]]]] [[要素]]では、[[雛形内容]]の [[adopt]] [SRC[>>26]]
]FIG]

[HISTORY[
[27] >>9 は [[adopting steps]] が導入される以前に規定されたため、>>33 まで
「[CODE(DOMa)@en[[[ownerDocument]]]]が変化した時」という表現になっていました。
[[adopt]] はそれ以外でも発生しますが、実質的には同じでした。

[28] >>32 以前の [[DOM Standard]] は [[adopt]] された[[節点]] ([[根]]) に対して [[adopting steps]]
を呼ぶと言っていますが、 [[HTML Standard]] は変更が発生した[[節点]]すべてに対して [[adopting steps]]
が呼ばれることを期待していて、齟齬がありました。
]HISTORY]

;; [3] >>16 の[[削除]]操作内で [[removing steps]] も実行されます。

-*-*-

[78] 
[[養子化]]は、その[[節点]]だけでなく[[子孫]]にまで影響が及びます。
[[影木]]があれば、そちらにも影響が及びます。

[79] 
[[養子化]]の時点で[F[親]]があれば、[[削除]] (親子関係が解消) されます。
従って[[養子化]]の影響は ([[子]]の[[削除]]を除き)
[[祖先]]には及びません。


[76] 
[CODE[DocumentFragment]] は[F[ホスト]]を持つ場合には、
同時にのみ[[養子化]]されることになっています。

[55] [[影根]]を [CODE[adoptNode]] (>>72)
や [CODE[importNode]] に引き渡すと、
[[例外]]を[[投げ]]ることになっています。その他[[養子化]]が呼び出される場面では、
[[影根]]が(単独で)[[養子化]]されることはありません。

;; [77] よって[[影根]]は常に[[影ホスト]]と同じ[[文書]]に属します。

-*-*-

[80] 
[[養子化]]は、

- [[節点の挿入]]
- [CODE[adoptNode]]

から呼び出されます。

* [CODE(DOMi)@en[Document]] インターフェイス [CODE(DOMm)@en[adoptNode]] メソッド (DOM)

[20] 
[CODE[Document]]
[[オブジェクト]]の
[DFN[[CODE(DOMm)@en[adoptNode]]]] [[メソッド]]は、
指定した[[節点]]をその[[文書]]へと[[養子化]]します。 [SRC[>>11]]

[21] 
具体的には、次のようにしなければ[MUST[なりません]] [SRC[>>11]]。

[FIG(steps)[

= [63] [VAR[文書]]を、[[文脈オブジェクト]]に設定します。
= [64] [VAR[節点]]を、第1引数を [CODE[Node]] として解釈した結果に設定します。
= [22] [CODE[CEReactions]]:
== [62] 
[VAR[節点]]の[F[節点型]]が[[文書]]の場合、
=== [65] 
[CODE[NotSupportedError]] [CODE[DOMException]] を[[投げ]]、
ここで停止します。
== [66] 
[VAR[節点]]が[[影根]]の場合、
=== [67] 
[CODE[HierarchyRequestError]] [CODE[DOMException]] を[[投げ]]、
ここで停止します。
== [68] 
[VAR[節点]]が [CODE[DocumentFragment]] で、
[VAR[節点]]の[F[ホスト]]が [CODE[null]] で''ない''場合、
=== [69] 
[VAR[節点]]を返し [SRC[仕様書になし]]、
ここで停止します。
== [70] 
[VAR[節点]]を[[文書]]に[[養子化]]します。
== [71] 
[VAR[節点]]を返します。
]FIG]

[72] 
つまり[[引数]]の[[節点]]を[[養子化]]するのですが、
[CODE[DocumentFragment]]
のとき特殊な挙動になります。
[CODE[DocumentFragment]] は3種類ありますが、そのうち2種類は[F[ホスト]]があります。
[F[ホスト]]がある [CODE[DocumentFragment]]
は、
[F[ホスト]]と同時にのみ[[養子化]]できます [SRC[>>58]] (>>76)。
[[例外]]を返したり何もしなかったりするのは、[[後方互換性]]のためとされます
[SRC[>>58]]。
この処理は[TIME[令和元(2019)年][2019]]の改正で明文化されました [SRC[>>56]] が、
それ以前の
[[Webブラウザー]]の処理は曖昧でした。

;; [73] そのときの修正ミスで何も返さないケースが生じていますが (>>69)、
[[Chrome]] では常に[VAR[節点]]が返されるようです。

[74] 
この[[メソッド]]は常に[[引数]]をそのまま返します。つまりあまり意味はありません。
[[chaining]] の便宜とも思われますが、 [[DOM]] にはそういうのはあまりないので、
どうなのでしょう。 ([CODE[appendChild]] に近いパターンなので、やはりそうなのかもしれませんが。)

;; [75] 
[[DOM3]] は[[文書]]が異なる[[DOM実装]]に属することも想定しているので、
もしかすると[[引数]]と[[返値]]が違うケースがあったのかもしれません。
しかし [[DOM3]] はそのへんのアーキテクチャーをあまりはっきり語っていなかったので、
その場合に[[引数]]の[[節点]]オブジェクトはその後どうなってしまうのかなど、
謎が多いです。

-*-*-

[23] 
[CODE[adoptNode]]
[[メソッド]]は、
[[DOM3]] で追加されたものでした。
[[DOM3]] 仕様上は明示的に [CODE(DOMm)@en[[[adoptNode]]]]
を呼ばなければ [CODE(DOMm)@en[[[adoptChild]]]] などで違う[[文書]]に挿入することができませんでした。

[61] 
しかし現実の [[Webブラウザー]]は当時から自動的に [[adopt]] する実装にほぼなっていました。
現在の [CITE[[[DOM Standard]]]]
はそちらの動作を採用しているため、
この[[メソッド]]が必要になる場面はほとんどありません。



* 歴史

[1]
[CITE[[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>
([[名無しさん]] [WEAK[2006-09-10 04:25:33 +00:00]])

[2]
[[原始文書]]と[[対象文書]]が同じ場合に
[CODE(DOMi)@en[[[UserDataHandler]]]] があれば呼ばれるのかどうか、
[[メソッド]]の返す値は何かは明記されていません。

[4]
[CODE(DOMi)@en[[[UserDataHandler]]]] が呼ばれるタイミングは明記されていません。
(複数の[[節点]]が同時に[[養子縁組]]されるとき、
すべての[[節点]]が[[養子縁組]]し終えてから呼ばれるのか?
どの順番で呼ばれるのか?)
([[名無しさん]])

[5]
[CODE(DOMi)@en[[[Document]]]] や 
[CODE(DOMi)@en[[[DocumentType]]]] を[[養子縁組]]しようとすると
[CODE(DOMc)@en[[[NOT_SUPPORTED_ERR]]]]
ですが、 [CODE(DOMi)@en[[[Entity]]]] や
[CODE(DOMi)@en[[[Notation]]]] だとどうなるのかは不明です。

[6]
[CITE@en[Re: ''''''[''''''dom'''''']'''''' Need to describe the interaction of adoptNode with  prototype  chains]]
( ([[Boris Zbarsky]] 著, [TIME[2013-01-17 01:27:26 +09:00]] 版))
<http://lists.w3.org/Archives/Public/www-dom/2013JanMar/0075.html>

[7] [CITE@en[Web Applications 1.0 r8270     Share the ownerDocument of template contents amongst the templates of a document.]]
( ([TIME[2013-11-13 06:36:00 +09:00]] 版))
<http://html5.org/tools/web-apps-tracker?from=8269&to=8270>

[8] [CITE[Index of /~stewart/css/html-options]]
([TIME[2010-03-04 09:46:12 +09:00]] 版)
<http://www.metahusky.net/~stewart/css/html-options/>

[REFS[
- [29] [CITE[Make the adopt hook more generic. https://www.w3.org/Bugs/Public/show_bu... · e50fd71 · whatwg/dom]]
( ([TIME[2014-04-11 23:02:31 +09:00]] 版))
<https://github.com/whatwg/dom/commit/e50fd7138f1bf288c4fa0b92f1673359a3affadb>
- [30] [CITE@en[Web Applications 1.0 r8509     Make <img> reload if inserting it into a new doc causes the URL to change (note that exactly what this does depends on whether the browser's 'list of available images' is maintained per-Doc, or whether there's only one list per origin)]] ([TIME[2014-02-25 07:53:00 +09:00]] 版) <http://html5.org/tools/web-apps-tracker?from=8508&to=8509>
]REFS]

[31] [[adopting steps]] は[[要素の基底URL]]の処理の一般化として >>29 で導入されました。

[REFS[
- [32] [CITE@en[Close #66: run the adopting steps recursively · whatwg/dom@5697cf4]] ([TIME[2015-09-08 19:43:43 +09:00]] 版) <https://github.com/whatwg/dom/commit/5697cf4f6fbc00b4b16373c2fdc5cc2b22e7cdeb>
- [33] [CITE@en[Close #103: use "adopting steps" from DOM and add ID · whatwg/html@a9890f1]] ([TIME[2015-09-08 19:50:25 +09:00]] 版) <https://github.com/whatwg/html/commit/a9890f11b5ddfff95fdf1f255151a34c9ebf9d59>
]REFS]

[34] [CITE@en[Make two loops to adopt a node · whatwg/dom@718ba4a]]
([TIME[2015-09-22 11:04:25 +09:00]] 版)
<https://github.com/whatwg/dom/commit/718ba4aeade05a08e8fafee18cf2fb07e7e7f806>

[35] [CITE@en[Fix #146: only run adopting steps when changing documents · whatwg/dom@bb69d0b]]
([TIME[2016-01-30 21:05:15 +09:00]] 版)
<https://github.com/whatwg/dom/commit/bb69d0b0b280bf283550f2c21cabd0e6aa1d4cfc>

[37] [CITE@en[Add ''''''[''''''CEReactions'''''']'''''' annotations to mutating methods · whatwg/dom@3cd02d1]]
([TIME[2016-04-26 19:07:48 +09:00]] 版)
<https://github.com/whatwg/dom/commit/3cd02d139c159a31fbb400e03932652c72fc7812>

[39] [CITE@en[Un-customify adopted elements]]
( ([[domenic]]著, [TIME[2016-06-01 20:24:12 +09:00]]))
<https://github.com/whatwg/dom/commit/e417f9f4ca5aa16f11b8e04378f8c3425554b0fd>

[42] [CITE@en[Set the stage for new custom element adoption semantics]]
([[domenic]]著, [TIME[2016-07-21 18:25:26 +09:00]])
<https://github.com/whatwg/dom/commit/674e9343c811b178b5d1821e469682df0aa616f9>

[52] [CITE@en[Pass the old and new document to adoptedCallback]]
([[domenic]]著, [TIME[2016-08-16 16:50:20 +09:00]])
<https://github.com/whatwg/dom/commit/026a77291fe09f3d4880775e03bbb875fd90f833>

[53] [CITE@en[Make Attr inherit from Node again]]
([[annevk]]著, [TIME[2016-08-19 21:44:07 +09:00]])
<https://github.com/whatwg/dom/commit/625a0747f137454c155a7b577a9e45be1aa35a34>


- [56] 
[CITE@en[Run adopt as part of insert]], [[annevk]], [TIME[2019-12-11 17:56:04 +09:00]], [TIME[2023-12-03T05:29:05.000Z]] <https://github.com/whatwg/dom/commit/c825ceaf3cb77943f487f85533d8be79bccd2fe3>
- [57] [CITE@en[Adoption and DocumentFragment by annevk · Pull Request #16348 · web-platform-tests/wpt · GitHub]], [TIME[2023-12-03T05:29:19.000Z]] <https://github.com/web-platform-tests/wpt/pull/16348>
- [58] 
[CITE@en[Don't allow adopting DocumentFragment of a template element · Issue #744 · whatwg/dom · GitHub]], [TIME[2023-12-03T05:29:28.000Z]] <https://github.com/whatwg/dom/issues/744>
- [59] 
[CITE@en[Run adopt as part of insert by annevk · Pull Request #754 · whatwg/dom · GitHub]], [TIME[2023-12-03T05:29:41.000Z]] <https://github.com/whatwg/dom/pull/754>


[60] >>56
[CODE[DocumentFragment]] の扱いが修正されました。



