From 8a4f7c46c1169ac1708faf38bd7c5243837a6522 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fran=C3=A7ois=20Daoust?= <fd@w3.org>
Date: Mon, 22 Apr 2024 07:50:46 +0200
Subject: [PATCH] Patch `cancel` event to refine bubbling information (#1220)

As discussed in #1212, the `cancel` event bubbles on `HTMLInputElement`,
but it does not bubble on `HTMLDialogElement`. It does not bubble on
`CloseWatcher` either but that's because `CloseWatcher` is not part of a
bubbling tree in any case.

Events extraction cannot automatically get this nuance, be it only because it
only sees `HTMLElement` as target interface for the event, and not
`HTMLInputElement` and `HTMLDialogElement`. In practice, it claims that the
event bubbles, which is neither wrong nor right.

This patch restricts the `cancel` entry in the HTML events extract to only
target `HTMLInputElement`, in order to create the right bubbling entry. And
it creates another `cancel` entry which does not bubble for `HTMLDialogElement`
and `CloseWatcher`.

With this patch (and the new version of Reffy), we should end up with the
following entry in the consolidated `events.json` file, which captures the
fact that:
- the event bubbles on `HTMLInputElement`
- the event does not bubble on `HTMLDialogElement`
- the concept of bubbling is meaningless on `CloseWatcher`

```json
{
  "href": "https://html.spec.whatwg.org/multipage/indices.html#event-cancel",
  "src": {
    "format": "summary table",
    "href": "https://html.spec.whatwg.org/multipage/indices.html#event-cancel"
  },
  "type": "cancel",
  "targets": [
    {
      "target": "HTMLInputElement",
      "bubbles": true,
      "bubblingPath": [
        "Node",
        "Document",
        "Window"
      ]
    },
    {
      "target": "CloseWatcher"
    },
    {
      "target": "HTMLDialogElement",
      "bubbles": false
    }
  ],
  "interface": "Event"
}
```
---
 tools/amend-event-data.js | 29 +++++++++++++++++++++++++----
 1 file changed, 25 insertions(+), 4 deletions(-)

diff --git a/tools/amend-event-data.js b/tools/amend-event-data.js
index 3b38211dbe83..3310664b245e 100644
--- a/tools/amend-event-data.js
+++ b/tools/amend-event-data.js
@@ -81,9 +81,9 @@ const patches = {
       pattern: { type: /^(cut|clipboardchange|paste|copy)$/ },
       matched: 4,
       change: {
-	interface: "ClipboardEvent",
+        interface: "ClipboardEvent",
         targets: ["GlobalEventHandlers"],
-	bubbles: true
+        bubbles: true
       }
     }
   ],
@@ -183,15 +183,36 @@ const patches = {
       matched: 7,
       change: { interface: 'DragEvent', bubbles: true }
     },
+    // The "HTMLElement" base interface receives most HTML events in theory,
+    // but some of the events only fire on specific HTML elements in practice.
+    // The following updates refine the target interfaces of these events.
+    // (This is not a temporary fix: "HTMLElement" is the correct target
+    // interface from a spec perspective, that's where the event handlers are
+    // defined)
+    // Also, the "cancel" event bubbles on input elements but not on other
+    // target interfaces, so we need to duplicate the entry in the extract.
     {
       pattern: { type: "cancel"},
       matched: 1,
-      change: { targets: ["HTMLDialogElement", "HTMLInputElement"] }
+      change: { targets: ["HTMLInputElement"] }
+    },
+    {
+      add: {
+        type: "cancel",
+        interface: "Event",
+        bubbles: false,
+        targets: ["CloseWatcher", "HTMLDialogElement"],
+        href: "https://html.spec.whatwg.org/multipage/indices.html#event-cancel",
+        src: {
+          format: "summary table",
+          href: "https://html.spec.whatwg.org/multipage/indices.html#event-cancel"
+        }
+      }
     },
     {
       pattern: { type: "close"},
       matched: 1,
-      change: { targets: ["HTMLDialogElement"   ] }
+      change: { targets: ["CloseWatcher", "HTMLDialogElement", "MessagePort"] }
     },
     {
       pattern: { type: "change", targets: "HTMLElement"},