From 9dffbc8f0b41d86e538f460911460d4a8b346e95 Mon Sep 17 00:00:00 2001 From: dandalf Date: Fri, 12 Sep 2025 10:28:53 -0600 Subject: [PATCH 1/6] added override and updated onerror for htmlelement --- baselines/dom.generated.d.ts | 9 +++++++- baselines/ts5.5/dom.generated.d.ts | 9 +++++++- baselines/ts5.6/dom.generated.d.ts | 9 +++++++- inputfiles/overridingTypes.jsonc | 7 ++++++ src/build/emitter.ts | 31 ++++++++++++++++++++++++-- unittests/files/onerror.ts | 35 ++++++++++++++++++++++++++++++ 6 files changed, 95 insertions(+), 5 deletions(-) create mode 100644 unittests/files/onerror.ts diff --git a/baselines/dom.generated.d.ts b/baselines/dom.generated.d.ts index 604beb99a..a1c1f942d 100644 --- a/baselines/dom.generated.d.ts +++ b/baselines/dom.generated.d.ts @@ -14026,7 +14026,7 @@ interface HTMLElementEventMap extends ElementEventMap, GlobalEventHandlersEventM * * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement) */ -interface HTMLElement extends Element, ElementCSSInlineStyle, ElementContentEditable, GlobalEventHandlers, HTMLOrSVGElement { +interface HTMLElement extends Element, ElementCSSInlineStyle, ElementContentEditable, Omit, HTMLOrSVGElement { /** * The **`HTMLElement.accessKey`** property sets the keystroke which a user can press to jump to a given element. * @@ -14117,6 +14117,13 @@ interface HTMLElement extends Element, ElementCSSInlineStyle, ElementContentEdit * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/offsetWidth) */ readonly offsetWidth: number; + /** + * The error event is fired on an element when a resource failed to load, or can't be used. + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/error_event) + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/error_event) + */ + onerror: (((event: Event) => any) | ((event: UIEvent) => any)) | null; /** * The **`outerText`** property of the HTMLElement interface returns the same value as HTMLElement.innerText. * diff --git a/baselines/ts5.5/dom.generated.d.ts b/baselines/ts5.5/dom.generated.d.ts index d5ca4f096..1e1b41f7c 100644 --- a/baselines/ts5.5/dom.generated.d.ts +++ b/baselines/ts5.5/dom.generated.d.ts @@ -14013,7 +14013,7 @@ interface HTMLElementEventMap extends ElementEventMap, GlobalEventHandlersEventM * * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement) */ -interface HTMLElement extends Element, ElementCSSInlineStyle, ElementContentEditable, GlobalEventHandlers, HTMLOrSVGElement { +interface HTMLElement extends Element, ElementCSSInlineStyle, ElementContentEditable, Omit, HTMLOrSVGElement { /** * The **`HTMLElement.accessKey`** property sets the keystroke which a user can press to jump to a given element. * @@ -14104,6 +14104,13 @@ interface HTMLElement extends Element, ElementCSSInlineStyle, ElementContentEdit * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/offsetWidth) */ readonly offsetWidth: number; + /** + * The error event is fired on an element when a resource failed to load, or can't be used. + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/error_event) + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/error_event) + */ + onerror: (((event: Event) => any) | ((event: UIEvent) => any)) | null; /** * The **`outerText`** property of the HTMLElement interface returns the same value as HTMLElement.innerText. * diff --git a/baselines/ts5.6/dom.generated.d.ts b/baselines/ts5.6/dom.generated.d.ts index 23672a6c7..5e5b05f5b 100644 --- a/baselines/ts5.6/dom.generated.d.ts +++ b/baselines/ts5.6/dom.generated.d.ts @@ -14026,7 +14026,7 @@ interface HTMLElementEventMap extends ElementEventMap, GlobalEventHandlersEventM * * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement) */ -interface HTMLElement extends Element, ElementCSSInlineStyle, ElementContentEditable, GlobalEventHandlers, HTMLOrSVGElement { +interface HTMLElement extends Element, ElementCSSInlineStyle, ElementContentEditable, Omit, HTMLOrSVGElement { /** * The **`HTMLElement.accessKey`** property sets the keystroke which a user can press to jump to a given element. * @@ -14117,6 +14117,13 @@ interface HTMLElement extends Element, ElementCSSInlineStyle, ElementContentEdit * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/offsetWidth) */ readonly offsetWidth: number; + /** + * The error event is fired on an element when a resource failed to load, or can't be used. + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/error_event) + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/error_event) + */ + onerror: (((event: Event) => any) | ((event: UIEvent) => any)) | null; /** * The **`outerText`** property of the HTMLElement interface returns the same value as HTMLElement.innerText. * diff --git a/inputfiles/overridingTypes.jsonc b/inputfiles/overridingTypes.jsonc index fc9172285..5fca399d8 100644 --- a/inputfiles/overridingTypes.jsonc +++ b/inputfiles/overridingTypes.jsonc @@ -404,6 +404,13 @@ // Blink only as of 2024-11 "overrideType": "boolean", "nullable": false + }, + "onerror": { + "name": "onerror", + "nullable": true, + "overrideType": "((event: Event) => any) | ((event: UIEvent) => any)", + "comment": "The error event is fired on an element when a resource failed to load, or can't be used. \n [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/error_event)", + "mdnUrl": "https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/error_event" } } }, diff --git a/src/build/emitter.ts b/src/build/emitter.ts index cd9f2cffe..2faf49490 100644 --- a/src/build/emitter.ts +++ b/src/build/emitter.ts @@ -31,6 +31,17 @@ const extendConflictsBaseTypes: Record< }, }; +const extendConflictsInterfaces: Record< + string, + { overrideMap: Record } +> = { + HTMLElement: { + overrideMap: { + GlobalEventHandlers: 'Omit', + }, + }, +}; + // Namespaces that have been in form of interfaces for years // and can't be converted to namespaces without breaking type packages const namespacesAsInterfaces = ["console"]; @@ -1270,7 +1281,7 @@ export function emitWebIdl( } function processMixinName(mixinName: string) { - if (allInterfacesMap[mixinName].typeParameters?.length === 1) { + if (allInterfacesMap[mixinName]?.typeParameters?.length === 1) { return `${mixinName}<${i.name}>`; } return mixinName; @@ -1293,11 +1304,27 @@ export function emitWebIdl( `interface ${getNameWithTypeParameters(i.typeParameters, processedIName)}`, ); - const finalExtends = [i.extends || "Object"] + // if (i.implements && extendConflictsInterfaces[i.name]?.implements?.length) { + // i.implements = extendConflictsInterfaces[i.name]?.implements; + // } + + let finalExtends = [i.extends || "Object"] .concat(getImplementList(i.name).map(processMixinName)) + // .concat(extendConflictsInterfaces[i.name]?.extendType ?? []) .filter((i) => i !== "Object") .map(processIName); + if (finalExtends.length && extendConflictsInterfaces[i.name]?.overrideMap) { + finalExtends = finalExtends.reduce((agg, item) => { + if (extendConflictsInterfaces[i.name]?.overrideMap[item]) { + agg.push(extendConflictsInterfaces[i.name]?.overrideMap[item]); + return agg; + } + agg.push(item); + return agg; + }, [] as string[]); + } + if (finalExtends.length) { printer.print(` extends ${assertUnique(finalExtends).join(", ")}`); } diff --git a/unittests/files/onerror.ts b/unittests/files/onerror.ts new file mode 100644 index 000000000..aadfcf753 --- /dev/null +++ b/unittests/files/onerror.ts @@ -0,0 +1,35 @@ +/** + * window.onerror works as intended with global event handler + */ +window.onerror = (message, src, lineno, colno, error) => { + if (message && src && lineno && colno && error) { + return; + } +}; + + +const div: HTMLElement = document.createElement("div"); + + +/** + * HTMLElement.onerror works with a single event arg, UIEvent + */ +div.onerror = (event: UIEvent) => { + if (event) { + return; + } +}; +/** + * HTMLElement.onerror works with a single event arg, Event + */ +div.onerror = (event: Event) => { + if (event) { + return; + } +}; + + +/** + * HTMLElement onerror is nullable + */ +div.onerror = null; From 9ece70dac4960ca544ab07ece76e5630556d6013 Mon Sep 17 00:00:00 2001 From: dandalf Date: Sat, 13 Sep 2025 01:09:48 -0600 Subject: [PATCH 2/6] added clarifying comments --- src/build/emitter.ts | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/build/emitter.ts b/src/build/emitter.ts index 2faf49490..1e1715f19 100644 --- a/src/build/emitter.ts +++ b/src/build/emitter.ts @@ -31,6 +31,12 @@ const extendConflictsBaseTypes: Record< }, }; +/** + * There are situations where extended types properties or methods need + * overridden by the implementing interface. Use this to register those interfaces + * the key is the implementing interface, the override map key is the interface you want to override + * the value overrides a type + */ const extendConflictsInterfaces: Record< string, { overrideMap: Record } @@ -1304,19 +1310,20 @@ export function emitWebIdl( `interface ${getNameWithTypeParameters(i.typeParameters, processedIName)}`, ); - // if (i.implements && extendConflictsInterfaces[i.name]?.implements?.length) { - // i.implements = extendConflictsInterfaces[i.name]?.implements; - // } - + // build the extends list for a given interface let finalExtends = [i.extends || "Object"] .concat(getImplementList(i.name).map(processMixinName)) - // .concat(extendConflictsInterfaces[i.name]?.extendType ?? []) .filter((i) => i !== "Object") .map(processIName); + // overrides the interface's extends with any conflicts + // this is a separate filter to make sure we only override conflicts when + // they exist if (finalExtends.length && extendConflictsInterfaces[i.name]?.overrideMap) { finalExtends = finalExtends.reduce((agg, item) => { + // check for the conflict if (extendConflictsInterfaces[i.name]?.overrideMap[item]) { + // overwrite the conflict agg.push(extendConflictsInterfaces[i.name]?.overrideMap[item]); return agg; } From fc80646f14a3b19581ce62e4cb27cc2aea9044bb Mon Sep 17 00:00:00 2001 From: dandalf Date: Sat, 13 Sep 2025 20:14:04 -0600 Subject: [PATCH 3/6] added addEventListener override --- baselines/dom.generated.d.ts | 1 + baselines/ts5.5/dom.generated.d.ts | 1 + baselines/ts5.6/dom.generated.d.ts | 1 + inputfiles/overridingTypes.jsonc | 9 +++++++-- unittests/files/eventlistener.ts | 28 ++++++++++++++++++++++++++++ unittests/files/onerror.ts | 1 + 6 files changed, 39 insertions(+), 2 deletions(-) diff --git a/baselines/dom.generated.d.ts b/baselines/dom.generated.d.ts index a1c1f942d..9e959aa3c 100644 --- a/baselines/dom.generated.d.ts +++ b/baselines/dom.generated.d.ts @@ -14190,6 +14190,7 @@ interface HTMLElement extends Element, ElementCSSInlineStyle, ElementContentEdit * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/togglePopover) */ togglePopover(options?: boolean): boolean; + addEventListener(type: string, listener: ((event: Event) => void) | ((event: UIEvent) => void)): void; addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; diff --git a/baselines/ts5.5/dom.generated.d.ts b/baselines/ts5.5/dom.generated.d.ts index 1e1b41f7c..14ca63a78 100644 --- a/baselines/ts5.5/dom.generated.d.ts +++ b/baselines/ts5.5/dom.generated.d.ts @@ -14177,6 +14177,7 @@ interface HTMLElement extends Element, ElementCSSInlineStyle, ElementContentEdit * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/togglePopover) */ togglePopover(options?: boolean): boolean; + addEventListener(type: string, listener: ((event: Event) => void) | ((event: UIEvent) => void)): void; addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; diff --git a/baselines/ts5.6/dom.generated.d.ts b/baselines/ts5.6/dom.generated.d.ts index 5e5b05f5b..a2856dd1b 100644 --- a/baselines/ts5.6/dom.generated.d.ts +++ b/baselines/ts5.6/dom.generated.d.ts @@ -14190,6 +14190,7 @@ interface HTMLElement extends Element, ElementCSSInlineStyle, ElementContentEdit * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/togglePopover) */ togglePopover(options?: boolean): boolean; + addEventListener(type: string, listener: ((event: Event) => void) | ((event: UIEvent) => void)): void; addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; removeEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; diff --git a/inputfiles/overridingTypes.jsonc b/inputfiles/overridingTypes.jsonc index 5fca399d8..93d9655e6 100644 --- a/inputfiles/overridingTypes.jsonc +++ b/inputfiles/overridingTypes.jsonc @@ -428,6 +428,11 @@ ] } } + }, + "addEventListener": { + "overrideSignatures": [ + "addEventListener(type: string, listener: ((event: Event) => void) | ((event: UIEvent) => void)): void" + ] } } } @@ -1235,7 +1240,7 @@ "name": "quality", "overrideType": "number" } - ], + ] } } }, @@ -1248,7 +1253,7 @@ "name": "quality", "overrideType": "number" } - ], + ] } } } diff --git a/unittests/files/eventlistener.ts b/unittests/files/eventlistener.ts index 021afbc3c..61332f4fa 100644 --- a/unittests/files/eventlistener.ts +++ b/unittests/files/eventlistener.ts @@ -7,3 +7,31 @@ document.addEventListener("arbitrary_invalid_event", { return ev.returnValue; } }); + +const divElement: HTMLElement = document.createElement("div"); + + +divElement.addEventListener( + "click", + (event: Event) => { + if (event) { + return; + } + }, + false, +); + +divElement.addEventListener( + "click", + (event: Event) => { + if (event) { + return; + } + } +); + +divElement.addEventListener("beep", (event: UIEvent) => { + if (event) { + return; + } +}); diff --git a/unittests/files/onerror.ts b/unittests/files/onerror.ts index aadfcf753..1fa109f1d 100644 --- a/unittests/files/onerror.ts +++ b/unittests/files/onerror.ts @@ -19,6 +19,7 @@ div.onerror = (event: UIEvent) => { return; } }; + /** * HTMLElement.onerror works with a single event arg, Event */ From 6ade076bce67ae80a7ed9b05a6d704e0eb2dbc0e Mon Sep 17 00:00:00 2001 From: dandalf Date: Sat, 13 Sep 2025 20:40:40 -0600 Subject: [PATCH 4/6] added comments --- baselines/dom.generated.d.ts | 5 +++++ baselines/ts5.5/dom.generated.d.ts | 5 +++++ baselines/ts5.6/dom.generated.d.ts | 5 +++++ inputfiles/overridingTypes.jsonc | 2 ++ 4 files changed, 17 insertions(+) diff --git a/baselines/dom.generated.d.ts b/baselines/dom.generated.d.ts index 9e959aa3c..b2acdf559 100644 --- a/baselines/dom.generated.d.ts +++ b/baselines/dom.generated.d.ts @@ -14190,6 +14190,11 @@ interface HTMLElement extends Element, ElementCSSInlineStyle, ElementContentEdit * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/togglePopover) */ togglePopover(options?: boolean): boolean; + /** + * The addEventListener() method of the EventTarget interface sets up a function that will be called whenever the specified event is delivered to the target. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener) + */ addEventListener(type: string, listener: ((event: Event) => void) | ((event: UIEvent) => void)): void; addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; diff --git a/baselines/ts5.5/dom.generated.d.ts b/baselines/ts5.5/dom.generated.d.ts index 14ca63a78..7c150cfd8 100644 --- a/baselines/ts5.5/dom.generated.d.ts +++ b/baselines/ts5.5/dom.generated.d.ts @@ -14177,6 +14177,11 @@ interface HTMLElement extends Element, ElementCSSInlineStyle, ElementContentEdit * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/togglePopover) */ togglePopover(options?: boolean): boolean; + /** + * The addEventListener() method of the EventTarget interface sets up a function that will be called whenever the specified event is delivered to the target. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener) + */ addEventListener(type: string, listener: ((event: Event) => void) | ((event: UIEvent) => void)): void; addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; diff --git a/baselines/ts5.6/dom.generated.d.ts b/baselines/ts5.6/dom.generated.d.ts index a2856dd1b..82f089491 100644 --- a/baselines/ts5.6/dom.generated.d.ts +++ b/baselines/ts5.6/dom.generated.d.ts @@ -14190,6 +14190,11 @@ interface HTMLElement extends Element, ElementCSSInlineStyle, ElementContentEdit * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/togglePopover) */ togglePopover(options?: boolean): boolean; + /** + * The addEventListener() method of the EventTarget interface sets up a function that will be called whenever the specified event is delivered to the target. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener) + */ addEventListener(type: string, listener: ((event: Event) => void) | ((event: UIEvent) => void)): void; addEventListener(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; diff --git a/inputfiles/overridingTypes.jsonc b/inputfiles/overridingTypes.jsonc index 93d9655e6..4d2ef4d03 100644 --- a/inputfiles/overridingTypes.jsonc +++ b/inputfiles/overridingTypes.jsonc @@ -430,6 +430,8 @@ } }, "addEventListener": { + "mdnUrl": "https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener", + "comment": "The addEventListener() method of the EventTarget interface sets up a function that will be called whenever the specified event is delivered to the target.", "overrideSignatures": [ "addEventListener(type: string, listener: ((event: Event) => void) | ((event: UIEvent) => void)): void" ] From 758e36cf9f2fcc99674bd10e7b90a0799f16274f Mon Sep 17 00:00:00 2001 From: dandalf Date: Sun, 14 Sep 2025 13:30:36 -0600 Subject: [PATCH 5/6] added override for svgelement --- baselines/dom.generated.d.ts | 15 ++++++++++++++- baselines/ts5.5/dom.generated.d.ts | 15 ++++++++++++++- baselines/ts5.6/dom.generated.d.ts | 15 ++++++++++++++- inputfiles/overridingTypes.jsonc | 18 ++++++++++++++++++ src/build/emitter.ts | 5 +++++ unittests/files/onerror.ts | 28 ++++++++++++++++++++++++++-- 6 files changed, 91 insertions(+), 5 deletions(-) diff --git a/baselines/dom.generated.d.ts b/baselines/dom.generated.d.ts index b2acdf559..824940abe 100644 --- a/baselines/dom.generated.d.ts +++ b/baselines/dom.generated.d.ts @@ -27399,9 +27399,16 @@ interface SVGElementEventMap extends ElementEventMap, GlobalEventHandlersEventMa * * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGElement) */ -interface SVGElement extends Element, ElementCSSInlineStyle, GlobalEventHandlers, HTMLOrSVGElement { +interface SVGElement extends Element, ElementCSSInlineStyle, Omit, HTMLOrSVGElement { /** @deprecated */ readonly className: any; + /** + * The error event is fired on an element when a resource failed to load, or can't be used. + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/error_event) + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/error_event) + */ + onerror: (((event: Event) => any) | ((event: UIEvent) => any)) | null; /** * The **`ownerSVGElement`** property of the SVGElement interface reflects the nearest ancestor svg element. * @@ -27414,6 +27421,12 @@ interface SVGElement extends Element, ElementCSSInlineStyle, GlobalEventHandlers * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGElement/viewportElement) */ readonly viewportElement: SVGElement | null; + /** + * The addEventListener() method of the EventTarget interface sets up a function that will be called whenever the specified event is delivered to the target. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener) + */ + addEventListener(type: string, listener: ((event: Event) => void) | ((event: UIEvent) => void)): void; addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; removeEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; diff --git a/baselines/ts5.5/dom.generated.d.ts b/baselines/ts5.5/dom.generated.d.ts index 7c150cfd8..3c3085773 100644 --- a/baselines/ts5.5/dom.generated.d.ts +++ b/baselines/ts5.5/dom.generated.d.ts @@ -27377,9 +27377,16 @@ interface SVGElementEventMap extends ElementEventMap, GlobalEventHandlersEventMa * * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGElement) */ -interface SVGElement extends Element, ElementCSSInlineStyle, GlobalEventHandlers, HTMLOrSVGElement { +interface SVGElement extends Element, ElementCSSInlineStyle, Omit, HTMLOrSVGElement { /** @deprecated */ readonly className: any; + /** + * The error event is fired on an element when a resource failed to load, or can't be used. + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/error_event) + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/error_event) + */ + onerror: (((event: Event) => any) | ((event: UIEvent) => any)) | null; /** * The **`ownerSVGElement`** property of the SVGElement interface reflects the nearest ancestor svg element. * @@ -27392,6 +27399,12 @@ interface SVGElement extends Element, ElementCSSInlineStyle, GlobalEventHandlers * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGElement/viewportElement) */ readonly viewportElement: SVGElement | null; + /** + * The addEventListener() method of the EventTarget interface sets up a function that will be called whenever the specified event is delivered to the target. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener) + */ + addEventListener(type: string, listener: ((event: Event) => void) | ((event: UIEvent) => void)): void; addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; removeEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; diff --git a/baselines/ts5.6/dom.generated.d.ts b/baselines/ts5.6/dom.generated.d.ts index 82f089491..b2188af63 100644 --- a/baselines/ts5.6/dom.generated.d.ts +++ b/baselines/ts5.6/dom.generated.d.ts @@ -27399,9 +27399,16 @@ interface SVGElementEventMap extends ElementEventMap, GlobalEventHandlersEventMa * * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGElement) */ -interface SVGElement extends Element, ElementCSSInlineStyle, GlobalEventHandlers, HTMLOrSVGElement { +interface SVGElement extends Element, ElementCSSInlineStyle, Omit, HTMLOrSVGElement { /** @deprecated */ readonly className: any; + /** + * The error event is fired on an element when a resource failed to load, or can't be used. + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/error_event) + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/error_event) + */ + onerror: (((event: Event) => any) | ((event: UIEvent) => any)) | null; /** * The **`ownerSVGElement`** property of the SVGElement interface reflects the nearest ancestor svg element. * @@ -27414,6 +27421,12 @@ interface SVGElement extends Element, ElementCSSInlineStyle, GlobalEventHandlers * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGElement/viewportElement) */ readonly viewportElement: SVGElement | null; + /** + * The addEventListener() method of the EventTarget interface sets up a function that will be called whenever the specified event is delivered to the target. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener) + */ + addEventListener(type: string, listener: ((event: Event) => void) | ((event: UIEvent) => void)): void; addEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; removeEventListener(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; diff --git a/inputfiles/overridingTypes.jsonc b/inputfiles/overridingTypes.jsonc index 4d2ef4d03..254b09b25 100644 --- a/inputfiles/overridingTypes.jsonc +++ b/inputfiles/overridingTypes.jsonc @@ -1293,6 +1293,24 @@ "deprecated": true, "name": "className", "type": "any" + }, + "onerror": { + "name": "onerror", + "nullable": true, + "overrideType": "((event: Event) => any) | ((event: UIEvent) => any)", + "comment": "The error event is fired on an element when a resource failed to load, or can't be used. \n [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/error_event)", + "mdnUrl": "https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/error_event" + } + } + }, + "methods": { + "method": { + "addEventListener": { + "mdnUrl": "https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener", + "comment": "The addEventListener() method of the EventTarget interface sets up a function that will be called whenever the specified event is delivered to the target.", + "overrideSignatures": [ + "addEventListener(type: string, listener: ((event: Event) => void) | ((event: UIEvent) => void)): void" + ] } } } diff --git a/src/build/emitter.ts b/src/build/emitter.ts index 1e1715f19..45a240d79 100644 --- a/src/build/emitter.ts +++ b/src/build/emitter.ts @@ -46,6 +46,11 @@ const extendConflictsInterfaces: Record< GlobalEventHandlers: 'Omit', }, }, + SVGElement: { + overrideMap: { + GlobalEventHandlers: 'Omit', + }, + }, }; // Namespaces that have been in form of interfaces for years diff --git a/unittests/files/onerror.ts b/unittests/files/onerror.ts index 1fa109f1d..2c2db3a11 100644 --- a/unittests/files/onerror.ts +++ b/unittests/files/onerror.ts @@ -7,7 +7,6 @@ window.onerror = (message, src, lineno, colno, error) => { } }; - const div: HTMLElement = document.createElement("div"); @@ -29,8 +28,33 @@ div.onerror = (event: Event) => { } }; - /** * HTMLElement onerror is nullable */ div.onerror = null; + + +const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); + +/** + * SVGElement.onerror works with a single event arg, UIEvent + */ +svg.onerror = (event: UIEvent) => { + if (event) { + return; + } +}; + +/** + * SVGElement.onerror works with a single event arg, Event + */ +svg.onerror = (event: Event) => { + if (event) { + return; + } +}; + +/** + * SVGElement onerror is nullable + */ +svg.onerror = null; From 6893423ad565453aa569a040ed13bfd87fe33035 Mon Sep 17 00:00:00 2001 From: dandalf Date: Sun, 14 Sep 2025 14:04:23 -0600 Subject: [PATCH 6/6] updated svgsvgelement --- baselines/dom.generated.d.ts | 6 ++++++ baselines/ts5.5/dom.generated.d.ts | 6 ++++++ baselines/ts5.6/dom.generated.d.ts | 6 ++++++ inputfiles/overridingTypes.jsonc | 7 +++++++ unittests/files/eventlistener.ts | 27 +++++++++++++++++++++++++++ 5 files changed, 52 insertions(+) diff --git a/baselines/dom.generated.d.ts b/baselines/dom.generated.d.ts index 824940abe..98cb9b402 100644 --- a/baselines/dom.generated.d.ts +++ b/baselines/dom.generated.d.ts @@ -29789,6 +29789,12 @@ interface SVGSVGElement extends SVGGraphicsElement, SVGFitToViewBox, WindowEvent unsuspendRedraw(suspendHandleID: number): void; /** @deprecated */ unsuspendRedrawAll(): void; + /** + * The addEventListener() method of the EventTarget interface sets up a function that will be called whenever the specified event is delivered to the target. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener) + */ + addEventListener(type: string, listener: ((event: Event) => void) | ((event: UIEvent) => void)): void; addEventListener(type: K, listener: (this: SVGSVGElement, ev: SVGSVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; removeEventListener(type: K, listener: (this: SVGSVGElement, ev: SVGSVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; diff --git a/baselines/ts5.5/dom.generated.d.ts b/baselines/ts5.5/dom.generated.d.ts index 3c3085773..500cde6d5 100644 --- a/baselines/ts5.5/dom.generated.d.ts +++ b/baselines/ts5.5/dom.generated.d.ts @@ -29767,6 +29767,12 @@ interface SVGSVGElement extends SVGGraphicsElement, SVGFitToViewBox, WindowEvent unsuspendRedraw(suspendHandleID: number): void; /** @deprecated */ unsuspendRedrawAll(): void; + /** + * The addEventListener() method of the EventTarget interface sets up a function that will be called whenever the specified event is delivered to the target. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener) + */ + addEventListener(type: string, listener: ((event: Event) => void) | ((event: UIEvent) => void)): void; addEventListener(type: K, listener: (this: SVGSVGElement, ev: SVGSVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; removeEventListener(type: K, listener: (this: SVGSVGElement, ev: SVGSVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; diff --git a/baselines/ts5.6/dom.generated.d.ts b/baselines/ts5.6/dom.generated.d.ts index b2188af63..2b76ddcdf 100644 --- a/baselines/ts5.6/dom.generated.d.ts +++ b/baselines/ts5.6/dom.generated.d.ts @@ -29789,6 +29789,12 @@ interface SVGSVGElement extends SVGGraphicsElement, SVGFitToViewBox, WindowEvent unsuspendRedraw(suspendHandleID: number): void; /** @deprecated */ unsuspendRedrawAll(): void; + /** + * The addEventListener() method of the EventTarget interface sets up a function that will be called whenever the specified event is delivered to the target. + * + * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener) + */ + addEventListener(type: string, listener: ((event: Event) => void) | ((event: UIEvent) => void)): void; addEventListener(type: K, listener: (this: SVGSVGElement, ev: SVGSVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; removeEventListener(type: K, listener: (this: SVGSVGElement, ev: SVGSVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void; diff --git a/inputfiles/overridingTypes.jsonc b/inputfiles/overridingTypes.jsonc index 254b09b25..94680b01c 100644 --- a/inputfiles/overridingTypes.jsonc +++ b/inputfiles/overridingTypes.jsonc @@ -1331,6 +1331,13 @@ "overrideType": "NodeListOf" } } + }, + "addEventListener": { + "mdnUrl": "https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener", + "comment": "The addEventListener() method of the EventTarget interface sets up a function that will be called whenever the specified event is delivered to the target.", + "overrideSignatures": [ + "addEventListener(type: string, listener: ((event: Event) => void) | ((event: UIEvent) => void)): void" + ] } } } diff --git a/unittests/files/eventlistener.ts b/unittests/files/eventlistener.ts index 61332f4fa..1dc446177 100644 --- a/unittests/files/eventlistener.ts +++ b/unittests/files/eventlistener.ts @@ -35,3 +35,30 @@ divElement.addEventListener("beep", (event: UIEvent) => { return; } }); + +const svgElement = document.createElementNS("http://www.w3.org/2000/svg", "svg"); + +svgElement.addEventListener( + "click", + (event: Event) => { + if (event) { + return; + } + }, + false, +); + +svgElement.addEventListener( + "click", + (event: Event) => { + if (event) { + return; + } + } +); + +svgElement.addEventListener("beep", (event: UIEvent) => { + if (event) { + return; + } +}); \ No newline at end of file