From def63ff49db833d958daaf6c0e0b4f26ba6ac32a Mon Sep 17 00:00:00 2001 From: Keith Cirkel Date: Mon, 9 Oct 2023 12:36:01 +0100 Subject: [PATCH] Allow for customisation of the "get the parent" algorithm This modifies the EventTarget IDL to allow assignment of a parent EventTarget to an EventTarget instance, while also modifying the "get the parent" algorithm to default to returning that instance. It also modifies the Event Dispatch algorithm to ensure that custom parent chains cannot cause loops. --- dom.bs | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/dom.bs b/dom.bs index b4c0abd3..19593d26 100644 --- a/dom.bs +++ b/dom.bs @@ -908,9 +908,14 @@ for historical reasons.

Interface {{EventTarget}}

+[Exposed=*]
+interface EventTargetInternals {
+  attribute EventTarget parent;
+};
+
 [Exposed=*]
 interface EventTarget {
-  constructor();
+  constructor(optional EventTargetCallback cb);
 
   undefined addEventListener(DOMString type, EventListener? callback, optional (AddEventListenerOptions or boolean) options = {});
   undefined removeEventListener(DOMString type, EventListener? callback, optional (EventListenerOptions or boolean) options = {});
@@ -930,6 +935,8 @@ dictionary AddEventListenerOptions : EventListenerOptions {
   boolean once = false;
   AbortSignal signal;
 };
+
+callback EventTargetCallback = undefined (EventTargetInternals internals);
 

An {{EventTarget}} object represents a target to which an event can be dispatched @@ -939,6 +946,50 @@ when something has occurred. list of zero or more event listeners). It is initially the empty list. +

Each {{EventTarget}} object has an associated attached internals (null +or an {{EventTargetInternals}} object), initially null. + +

Each {{EventTargetInternals}} object has an associated eventTarget (an {{EventTarget}} object). + +

The new EventTarget(cb) constructor steps are: + +

    +
  1. If cb is not null then: + +

      +
    1. Let eventTargetInternals a new {{EventTargetInternals}} instance. + +

    2. Set eventTargetInternals's eventTarget to + this. + +

    3. Invoke cb with « eventTargetInternals » and with this + as the callback this value. + +
    4. Set this's attached internals to + eventTargetInternals. +

    +
+ +

To set the parent given +an {{EventTargetInternals}} internals and {{EventTarget}} theParent: + +

    +
  1. If theParent is equal to internals' eventTarget then throw a + "{{HierarchyRequestError!!exception}}" {{DOMException}}. + +
  2. If theParent's attached internals + {{EventTargetInternals/parent}} is equal to internals' eventTarget thenthrow a "{{HierarchyRequestError!!exception}}" + {{DOMException}}. + +
  3. Set internal's eventTarget get the parent + algorithm to return theParent. + +
  4. Set internal's {{EventTargetInternals/parent}} to theParent. +
+

An event listener can be used to observe a specific event and consists of: @@ -1322,6 +1373,9 @@ property of the event being dispatched.

While parent is non-null:

    +
  1. If the event's path contains parent + then throw a "{{HierarchyRequestError!!exception}}" {{DOMException}}. +
  2. If slottable is non-null: