* 仕様書

[REFS[
- [53] [CITE@en-GB-x-hixie[HTML Standard]] ([TIME[2016-05-23 15:35:03 +09:00]]) <https://html.spec.whatwg.org/#extensibility-2:cereactions>
- [7] '''[CITE@en-GB-x-hixie[HTML Standard]] ([TIME[2016-05-14 09:55:50 +09:00]]) <https://html.spec.whatwg.org/#custom-element-reactions>'''
- [44] [CITE@en[DOM Standard]] ([TIME[2016-05-12 18:40:36 +09:00]]) <https://dom.spec.whatwg.org/#concept-node-insert>
- [40] [CITE@en[DOM Standard]] ([TIME[2016-05-12 18:40:36 +09:00]]) <https://dom.spec.whatwg.org/#concept-node-remove>
- [46] [CITE@en[DOM Standard]] ([TIME[2016-05-12 18:40:36 +09:00]]) <https://dom.spec.whatwg.org/#concept-element-attributes-change>
]REFS]

* 意味

[8] [DFN[[RUBYB[カスタム要素反応]@en[custom element reaction]]]] [SRC[>>7]] は、
[[カスタム要素]]に関する変化を通知する[[コールバック関数]]です。
次のものがあります。

[FIG(list members)[
: [[カスタム要素構築器]] :
[[要素の格上げ]]で実行されます。
: [CODE[connectedCallback]] :
[[要素]]が[[接続][節点の接続]]された際に実行されます。
: [CODE[disconnectedCallback]] :
[[要素]]が[[切断][節点の切断]]された際に実行されます。
: [CODE[adoptedCallback]] : 
[[要素]]が[[養子化]] (他の[[文書]]に移動) された際に実行されます。
: [CODE[attributeChangedCallback]] :
[[要素]]の[[内容属性]]の[[変更操作][属性の変更]]が発生した際に実行されます。
]FIG]

[9] [[カスタム要素構築器]]は、[[カスタム要素定義]]を作成する際に、
必ず指定します ([CODE(DOMm)@en[define]] [[メソッド]]の第2引数)。
それ以外は、[[カスタム要素構築器]]の [CODE[prototype]]
[[オブジェクト]]の[[プロパティー]]として、必要に応じて指定できます。

[12] [[カスタム要素構築器]]は、その時点ではまだ[F[カスタム][カスタム要素]]でない[[要素]]について実行されます。
それ以外の[[コールバック]]は、[[カスタム要素]]について実行されます。

[10] [[カスタム要素反応]]は、該当する [[DOM]] 操作が発生した時に実行されます。
複数の変更が発生する場合であっても、一連の変更がすべて適用された後、
呼び出し元に[[戻る]]直前にまとめて実行されます。
[[著者]]視点では [[DOM]] 操作中に同期的に呼び出されていますが、
[[利用者エージェント]]視点では [[DOM]] 操作直後に非同期的に呼び出しているので、
[[著者]]は [[DOM]] 操作の途中段階にアクセスすることはできませんし、
[[利用者エージェント]]は [[DOM]] 操作中の不安定な状態を[[著者]]に晒さずに済みます。

[11] ある[[カスタム要素]]について、ある操作群に対する[[カスタム要素反応]]群は、
必ず同じ順序で実行されることが保証されます。
複数の[[カスタム要素]]全体については ([[カスタム要素反応]]内で他の[[要素]]を変更する場合があるので)
保証されません。 [SRC[>>7]]

[99] 
[[カスタム要素反応器]]が[[節点木]]を[[操作][変異]]すると予期せぬ結果となることがあるため、
これを避ける[SHOULD[べき]]です。 [SRC[>>7]]

[EG[
[100] 例えば [CODE[connectedCallback]]
が呼ばれている[[要素]]が既に他の[[カスタム要素反応器]]によって[[切断]]されているかもしれません。
]EG]

* キュー

[70] 実行するべき[[カスタム要素反応]]は、 [[Webブラウザー]]によって[[要素]]ごとに管理されます。
[[要素]]ごとの[[キュー]]を使うので、[[要素]]ごとの実行順序は保証されますが、
異なる[[要素]]でどの順序で実行されるかは保証されません。

[16] [[要素]]は、[DFN[[F[[RUBYB[[[カスタム要素反応キュー]]]@en[custom element reaction queue]]]]]]を持ちます。
これは、[[格上げ反応]]または[[コールバック反応]]の[[キュー]]で、
初期状態は[[空]]です。 [SRC[>>7]]

;; [17] キューへの追加は、[[格上げ反応]]と[[コールバック反応]]の項を参照。

;; [77] [[push]]/[[pop]] の他に、[[要素の格上げ]]で空にされることがあります。

[71] 更に、どの[[要素]]に実行するべき[[カスタム要素反応]]が存在するかが、
[[要素キュー]]によって管理されます。

[14] [DFN[[RUBYB[[[要素キュー]]]@en[element queue]]]]は、
[[要素]]の[[キュー]]で、初期状態は[[空]]です。 [SRC[>>7]]

[13] [[関連する類似起源閲覧文脈群の単位]]は、
[DFN[[F[[RUBYB[[[カスタム要素反応群スタック]]]@en[custom element reactions stack]]]]]]を持ちます [SRC[>>7]]。

[FIG(list members)[
[FIGCAPTION[
[[カスタム要素反応群スタック]]
]FIGCAPTION]

: [F[スタック]] : [[要素キュー]]の[[スタック]]。初期状態は[[空]]。 [SRC[>>7]]
: [DFN[[F[[RUBYB[[[現在要素キュー]]]@en[current element queue]]]]]] :
[F[スタック]]の最上にある[[要素キュー]] [SRC[>>7]]。
: [DFN[[F[[RUBYB[[[バックアップ要素キュー]]]@en[backup element queue]]]]]] :
[[要素キュー]]。初期状態は[[空]]です。 [SRC[>>7]]
: [DFN[[F[[RUBYB[[[バックアップ要素キュー処理中]]]@en[processing the backup element queue]]]]]]フラグ :
初期状態は未設定。 [SRC[>>7]]
]FIG]

[72] [[構文解析器]]や [[DOM API]] 内部では、[[カスタム要素反応群スタック]]の本体[[スタック]]の[[要素キュー]]が使われます。
[[カスタム要素反応]]は同期的に呼び出され、そこから更に再帰的に[[カスタム要素反応]]が呼び出される可能性があるため、
[[要素キュー]]は[[スタック]]に積まれていくことになっています。

[73] [CODE(HTMLa)@en[contenteditable]] により[[利用者]]の操作で [[DOM]]
操作が行われた場合には、[F[バックアップ要素キュー]]が使われます [SRC[>>7]]。
[[カスタム要素反応]]は[[マイクロタスク]]で呼び出されます。

[15] [VAR[要素]]について[DFN[[RUBYB[適切な要素キューに要素を追加]@en[enqueue an element on the appropriate element queue]]]]するには、
次のようにします [SRC[>>7]]。
[FIG(steps)[
= [58] [[関連する類似起源閲覧文脈群の単位]]の[F[カスタム要素反応群スタック]]が[[空]]なら、
== [59] [VAR[要素]]を、[[関連する類似起源閲覧文脈群の単位]]の[F[カスタム要素反応群スタック]]の[F[バックアップ要素キュー]]に追加します。
== [60] [[関連する類似起源閲覧文脈群の単位]]の[F[カスタム要素反応群スタック]]の[F[バックアップ要素キュー処理中]]フラグが設定されていなければ、
=== [61] [[関連する類似起源閲覧文脈群の単位]]の[F[カスタム要素反応群スタック]]の[F[バックアップ要素キュー処理中]]フラグを設定します。
=== [62] >>65 の[[マイクロタスク]]を[[マイクロタスクをキューに追加]]します。
= [63] それ以外なら、
== [64] [VAR[要素]]を、[[関連する類似起源閲覧文脈群の単位]]の[F[カスタム要素反応群スタック]]の[F[現在要素キュー]]に追加します。
]FIG]

;; [68] この処理は、[[格上げ反応]]や[[コールバック反応]]の処理から呼び出されます。

[65] [[バックアップ要素キュー]]に関する[[マイクロタスク]]は、次のようにします [SRC[>>7]]。
[FIG(steps)[
= [66] [[関連する類似起源閲覧文脈群の単位]]の[F[カスタム要素反応群スタック]]の[F[バックアップ要素キュー]]の[[カスタム要素反応群の呼び出し]]をします。
= [67] [[関連する類似起源閲覧文脈群の単位]]の[F[カスタム要素反応群スタック]]の[F[バックアップ要素キュー処理中]]フラグを未設定にします。
]FIG]

[18] [[要素キュー]][VAR[キュー]]の[DFN[[RUBYB[カスタム要素反応群の呼び出し]@en[invoke custom element reactions]]]]は、
次のようにします [SRC[>>7]]。
[FIG(steps)[
= [19] [VAR[キュー]]の各[VAR[要素]]について、
== [20] [VAR[反応群]]を、[VAR[要素]]の[F[カスタム要素反応キュー]]に設定します。
== [21] [VAR[反応群]]が空でない限り、繰り返し、
=== [22] [VAR[反応]]を[VAR[反応群]]の最初の項目とし、これを[VAR[反応群]]から削除します。
=== [23] [VAR[反応群]]の種別により、
[FIG(switch)[
: [[格上げ反応]] :
[VAR[要素]]と[VAR[反応]]の[[カスタム要素定義]]について、[[要素の格上げ]]を実行します。
[[例外]]が[[投げ]]られたら、[[例外を報告]]します。
: [[コールバック反応]] :
[VAR[反応]]の[[コールバック関数]]を[[呼び出し][コールバック関数の呼び出し]]ます。
[VAR[反応群]]の引数リストを引き渡します。
[VAR[[[コールバックthis値]]]]は、[VAR[要素]]とします。
[[例外]]が[[投げ]]られたら、[[例外を報告]]します。
]FIG]
]FIG]

;; [24] これは、通常の [[DOM]] 操作に関しては [CODE(IDL xattr)@en[CEReactions]]
から、[[構文解析器]]に関しては[[字句の要素の作成]]や[[外来要素の挿入]]から呼び出されます。

* 拡張属性 [CODE(IDL xattr)@en[CEReactions]]

[25] [[Web IDL]] のいくつかの[[メンバー]]には、
[CODE(IDL xattr)@en[CEReactions]] [[拡張属性]]を指定できます [SRC[>>7]]。
[CODE(IDL xattr)@en[CEReactions]] は、
[[カスタム要素反応]]を適宜実行しなければならないことを表しています。

[26] この[[拡張属性]]は、[[操作]]、[[IDL属性]]、[[設定器]]、[[削除器]]''以外''に指定しては[MUST[なりません]]。
[[読み取り専用属性]]に指定しては[MUST[なりません]]。 [SRC[>>7]]

[27] この[[拡張属性]]は、[[引数]]を指定しては[MUST[なりません]] [SRC[>>7]]。

[28] この[[拡張属性]]が指定されている場合は、
当該[[メンバー]]の処理は、次のようにしなければ[MUST[なりません]] [SRC[>>7]]。

[FIG(steps)[
= [30] [[関連する類似起源閲覧文脈群の単位]]の[F[カスタム要素反応群スタック]]に、
[[要素キュー]]を [[push]] します。
= [90] [VAR[結果]]を、当該[[メンバー]]の処理を実行した結果に設定します。
= [31] [VAR[キュー]]を、[[関連する類似起源閲覧文脈群の単位]]の[F[カスタム要素反応群スタック]]から [[pop]] した結果に設定します。
= [32] [VAR[キュー]]について[[カスタム要素反応群の呼び出し]]を実行します。
= [29] [VAR[結果]]を返します。 ([VAR[結果]]は「[[例外]]が[[投げ]]られた」の場合もあります。)
]FIG]

[33] つまり、当該メンバーの処理中に [[DOM]] 操作が発生し、
[[カスタム要素反応]]を実行しなければならないことになったら、
当該メンバーの処理の最後にまとめて順に実行されます。

[34] この[[拡張属性]]は、 [[DOM]] に変更を加えるあらゆる [[Web IDL]]
の[[メンバー]]に付与されています。

[52] [[vendor prefix]] 付きの[[内容属性]]を[[反映]]する[[IDL属性]]は、
[CODE(IDL xattr)@en[CEReactions]] 付きでなければ[MUST[なりません]]
[SRC[>>53]]。

[69] その他 [[Webブラウザー]]独自 (非標準) の [[DOM]] 操作を伴う[[IDL属性]]や[[メソッド]]も、
[CODE(IDL xattr)@en[CEReactions]] 付きでなければ[MUST[なりません]] [SRC[>>7]]。

* 挿入手順群

[35] [[カスタム要素]]が[[文書に接続]]された際は、その旨を通知するため[[スクリプト]]が実行される可能性があります。
([[仕様書]]上は[[挿入手順群]]ではなく、[[挿入手順群]]の直後の別の処理として定義されています。)

[36] [[挿入]]は、[VAR[子孫]]について次のようにすることになっています [SRC[>>44]]。
[FIG(steps)[
= [37] [VAR[子孫]]が[[影を含む文書中]]なら、
== [38] [VAR[子孫]]が[F[カスタム]]なら、
=== [39] [[カスタム要素コールバック反応をキューに追加]]します。
[FIG(list members)[
: [VAR[要素]] : [VAR[子孫]]
: [VAR[コールバック名]] : [CODE[connectedCallback]]
: [VAR[引数リスト]] : [[空]]
]FIG]
== [50] それ以外なら、
=== [51] [VAR[子孫]]について[[要素の格上げの試行]]をします。
]FIG]

* 削除手順群

[41] [CODE(DOM)@en[disconnectedCallback]] の呼び出しは、[[仕様書]]上は[[削除手順群]]ではなく、
[[削除手順群]]の直後の別の処理として定義されています。

[42] [VAR[節点]]について、次のようにします [SRC[>>40]]。
[FIG(steps)[
= [43] [VAR[節点]]が[F[カスタム]]なら、
== [45] [[カスタム要素コールバック反応をキューに追加]]します。
[FIG(list members)[
: [VAR[要素]] : [VAR[節点]]
: [VAR[コールバック名]] : [CODE[disconnectedCallback]]
: [VAR[引数リスト]] : [[空]]
]FIG]
]FIG]

* 属性変更手順群

[47] [[仕様書]]上は、[[属性変更手順群]]ではなく、その直前に実行される別の処理として規定されています。
[VAR[要素]]、[VAR[局所名]]、[VAR[古い値]]、[VAR[値]]、[VAR[名前空間]]について、
次のようにします [SRC[>>46]]。
[FIG(steps)[
= [48] [VAR[要素]]が[F[カスタム]]なら、
== [49] [[カスタム要素コールバック反応をキューに追加]]します。
[FIG(list members)[
: [VAR[要素]] : [VAR[要素]]
: [VAR[コールバック名]] : [CODE[attributeChangedCallback]]
: [VAR[引数リスト]] : 
[FIG(list)[
- [VAR[局所名]]
- [VAR[古い値]]
- [VAR[値]]
- [VAR[名前空間]]
]FIG]
]FIG]
]FIG]

* 養子化手順群

[75] [[養子化手順群]]参照。

* 歴史

[1] [CITE@en[Add custom elements to HTML · whatwg/html@6e7eaa4]]
([TIME[2016-04-26 18:23:20 +09:00]] 版)
<https://github.com/whatwg/html/commit/6e7eaa4bd2912965fd83766f99f984f249531f3a>

[2] [CITE@en[Formalize custom element reactions · whatwg/html@27aa7bc]]
([TIME[2016-04-26 18:49:03 +09:00]] 版)
<https://github.com/whatwg/html/commit/27aa7bc4fa6f168654a8c858f0773e611f679b39>

[3] [CITE@en[Add ''''''[''''''CEReactions'''''']'''''' annotations to mutating methods · whatwg/dom@3cd02d1]]
([TIME[2016-04-26 19:05:42 +09:00]] 版)
<https://github.com/whatwg/dom/commit/3cd02d139c159a31fbb400e03932652c72fc7812>

[4] [CITE@en[Integrate callback invocation with IDL · Issue #186 · w3c/webcomponents]]
([TIME[2016-04-26 19:14:21 +09:00]] 版)
<https://github.com/w3c/webcomponents/issues/186>

[5] [CITE@en[DOM XSLTProcessor - WHATWG Wiki]]
([TIME[2016-04-21 04:49:20 +09:00]] 版)
<https://wiki.whatwg.org/wiki/DOM_XSLTProcessor>

[6] [CITE@en[Add ''''''[''''''CEReactions'''''']'''''' annotation to as · w3c/preload@b632000]]
([TIME[2016-05-01 14:00:58 +09:00]] 版)
<https://github.com/w3c/preload/commit/b632000d8bd32118d3b7833b7c0caca044329072>

[54] [CITE@en[Remove some redundant '''['''CEReactions''']''' for tables]]
( ([[domenic]]著, [TIME[2016-06-08 01:57:28 +09:00]]))
<https://github.com/whatwg/html/commit/c2dfb033b144775e37975c6740a2f5d7842e1b16>

[55] [CITE@en[Export the definitions of '''['''CEReactions''']''' and '''['''HTMLConstructor''']''']]
( ([[domenic]]著, [TIME[2016-06-21 07:33:25 +09:00]]))
<https://github.com/whatwg/html/commit/6e040bfecceb8aed7949abda383656e0bbf449e0>

[56] [CITE@en[Enqueue custom element reactions appropriately during upgrades]]
([[domenic]]著, [TIME[2016-06-06 16:44:11 +09:00]])
<https://github.com/whatwg/html/commit/2328ccf97b80cba7835df3dc5d1a687d51fbfcf4>

[57] [CITE@en[Take care of missing custom element reactions]]
([[domenic]]著, [TIME[2016-06-30 03:04:46 +09:00]])
<https://github.com/whatwg/html/commit/a57c88711c995356e44d019f5bd81d0cdedac2bf>

[74] [CITE@en[Convert custom element callbacks to Web IDL callback types]]
([[domenic]]著, [TIME[2016-06-30 02:10:53 +09:00]])
<https://github.com/whatwg/html/commit/be055730a11a8f952feb8fdb73e7caa01460e5a4>

[76] [CITE@en[Process custom element connectedCallback immediately during parsing]]
([[domenic]]著, [TIME[2016-08-24 15:32:24 +09:00]])
<https://github.com/whatwg/html/commit/ca818ee1c8458c3b862acd00d11779294cb89eea>

[78] [CITE@en[Remove old-fashioned vendor-specific extension advice]]
([[annevk]]著, [TIME[2016-10-13 02:28:15 +09:00]])
<https://github.com/whatwg/html/commit/76f88a4015d55273749c34238d250b7bdb1aff62>

[79] [CITE@en[Correct some '''['''CEReactions''']''' usage]]
([[annevk]]著, [TIME[2016-10-29 07:50:41 +09:00]])
<https://github.com/whatwg/html/commit/404f98bb543a244e5aeffe266d581f317e295598>

[80] [CITE@en[Fix which built-in elements can be customized]]
([[domenic]]著, [TIME[2016-11-17 01:31:58 +09:00]])
<https://github.com/whatwg/html/commit/7d6b279b0d2bc30752700155a043b65441fe12e3>

[81] [CITE@en[Tweak '''['''CEReactions''']''' definition and usage]]
([[domenic]]著, [TIME[2017-02-22 06:11:13 +09:00]])
<https://github.com/whatwg/html/commit/c422734d44ae9897c1700daf08bd415e0dc5f9e1>

[82] [CITE@en[Remove '''['''CEReactions''']''' on '''['''PutForwards''']''' readonly attribute]]
([[johndai1984]]著, [TIME[2017-04-12 19:54:45 +09:00]])
<https://github.com/whatwg/dom/commit/5f1a6065921790e35b81871928f6d861bc6d8d29>

[83] [CITE@en[Clarify the behavour if the custom element reaction throws any exception · Issue #2842 · whatwg/html]]
([TIME[2017-07-20 19:41:32 +09:00]])
<https://github.com/whatwg/html/issues/2842>

[84] [CITE@en[Add '''['''CEReactions''']''' to createElement()]]
([[annevk]]著, [TIME[2017-10-17 15:58:41 +09:00]])
<https://github.com/whatwg/dom/commit/fb6638fa3d02985e43782d8857edaa915d499261>

[85] [CITE@en[Add '''['''CEReactions''']''' to createElement() by annevk · Pull Request #506 · whatwg/dom]]
([TIME[2017-10-18 16:35:49 +09:00]])
<https://github.com/whatwg/dom/pull/506>

[86] [CITE@en[Clarify custom element reaction arguments passed]]
([[domenic]]著, [TIME[2017-10-21 06:47:04 +09:00]])
<https://github.com/whatwg/html/commit/c5019ae75d7dfaaf7829cf45c56700e97b24ea61>

[87] [CITE@en[Custom Elements Methods Clarification · Issue #2299 · whatwg/html]]
([TIME[2017-10-21 16:28:58 +09:00]])
<https://github.com/whatwg/html/issues/2299>

[88] [CITE@en[Clarify custom element reaction arguments passed by domenic · Pull Request #3125 · whatwg/html]]
([TIME[2017-10-21 16:29:26 +09:00]])
<https://github.com/whatwg/html/pull/3125>

[89] [CITE@en[Make '''['''CEReactions''']''''s treatment of exceptions explicit]]
([[domenic]]著, [TIME[2017-11-18 01:21:52 +09:00]])
<https://github.com/whatwg/html/commit/8b055c0497070731c526e8c0bb655af65fb4e10e>

[91] [CITE@en[How does CEReactions interact with thrown exceptions? · Issue #3217 · whatwg/html]]
([TIME[2017-11-18 15:01:38 +09:00]])
<https://github.com/whatwg/html/issues/3217>

[92] [CITE@en[Make '''['''CEReactions''']''''s treatment of exceptions explicit by domenic · Pull Request #3235 · whatwg/html]]
([TIME[2017-11-18 15:06:30 +09:00]])
<https://github.com/whatwg/html/pull/3235>

[93] [CITE@en[Hide `nonce` content attribute values. (#2369) by mikewest · Pull Request #2373 · whatwg/html]]
([TIME[2018-02-17 23:35:33 +09:00]])
<https://github.com/whatwg/html/pull/2373>

[94] [CITE@en[Fix and clarify some '''['''CEReactions''']''' annotations]]
([[domenic]]著, [TIME[2018-08-11 19:59:46 +09:00]])
<https://github.com/whatwg/html/commit/023c11216ca2ee1c653df09a594b98fca1323975>

[95] [CITE@en[nonce IDL attribute should have the semantics of CEReactions · Issue #3887 · whatwg/html]]
([TIME[2018-08-18 23:59:34 +09:00]])
<https://github.com/whatwg/html/issues/3887>

[96] [CITE@en[textarea's value IDL attribute doesn't need CEReactions · Issue #3889 · whatwg/html]]
([TIME[2018-08-18 23:59:51 +09:00]])
<https://github.com/whatwg/html/issues/3889>

[97] [CITE@en[Fix and clarify some '''['''CEReactions''']''' annotations by domenic · Pull Request #3901 · whatwg/html]]
([TIME[2018-08-19 00:00:00 +09:00]])
<https://github.com/whatwg/html/pull/3901>

[98] [CITE@en[Custom element reactions ought not to modify the node tree]]
([[annevk]]著, [TIME[2019-01-03 19:35:07 +09:00]])
<https://github.com/whatwg/html/commit/cc6c51d5f7461880ea93736256137c6bb565270c>

[101] [CITE@en[Always enqueue an element regardless of callback by annevk · Pull Request #4127 · whatwg/html]]
([TIME[2019-06-01 13:11:35 +09:00]])
<https://github.com/whatwg/html/pull/4127>

[102] [CITE@en[Presence of disconnectedCallback can expedite an invocation of connectedCallback · Issue #760 · w3c/webcomponents]]
([TIME[2019-06-01 13:13:10 +09:00]])
<https://github.com/w3c/webcomponents/issues/760>

[103] [CITE@en[Add a nonintuitive disconnectedCallback example by annevk · Pull Request #4237 · whatwg/html]]
([TIME[2019-06-01 13:14:36 +09:00]])
<https://github.com/whatwg/html/pull/4237>