From b5db7fac41c990df6c5cd80ead57f831c52671f7 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 | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 72 insertions(+), 1 deletion(-) diff --git a/dom.bs b/dom.bs index b4c0abd3..f5ef39de 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,70 @@ 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). + +

Each {{EventTargetInternals}} object has an associated parent (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. +

    +
+ +

The parent getter steps are to return this's +parent. + +

The parent setter steps are: + +

    +
  1. Let theParent be the given value. + +

  2. Let targets be a new list. + +

  3. Append this's eventTarget to targets. + +
  4. Let parent be theParent. + +

  5. +

    While parent is non-null:

    + +
      +
    1. If targets contains parent then throw a + "{{HierarchyRequestError!!exception}}" {{DOMException}}. + +
    2. Append parent to targets. + +
    3. Let parentInternals be parent's attached internals. + +
    4. Set parent to parentInternals's eventTarget. + +
    + +
  6. Set this's eventTarget get the parent + algorithm to return theParent. + +
  7. Set this's {{EventTargetInternals/parent}} to theParent. +
+

An event listener can be used to observe a specific event and consists of: