Skip to content

Commit a2ede18

Browse files
committed
Merge with master to keep being updated
2 parents 1c1acc1 + 9e73579 commit a2ede18

9 files changed

+1724
-818
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ The common steps to send a pull request are:
2929
1. Add missing elements to `inputfiles/addedTypes.json`, overriding elements to `inputfiles/overridingTypes.json`, or elements to remove to `inputfiles/removedTypes.json`.
3030
2. Run the build script locally to obtain new `dom.generated.d.ts` and `webworker.generated.d.ts`.
3131
3. Update the files in the `baselines` folder using the newly generated files
32-
under `generated` folder (`cp ./generated/* ./baseline/`).
32+
under `generated` folder (`cp ./generated/* ./baselines/`).
3333

3434
### When should a DOM API be included here?
3535

TS.fsx

+56-17
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ module InputJson =
175175

176176
let getItemByName (allItems: InputJsonType.Root []) (itemName: string) (kind: ItemKind) otherFilter =
177177
let filter (item: InputJsonType.Root) =
178-
OptionCheckValue itemName item.Name &&
178+
(OptionCheckValue itemName item.Name || OptionCheckValue (sprintf "%s?" itemName) item.Name) &&
179179
item.Kind.ToLower() = kind.ToString() &&
180180
otherFilter item
181181
allItems |> Array.tryFind filter
@@ -535,6 +535,7 @@ module Data =
535535
|> Array.map (fun i -> (i.Name, getEventHandler i))
536536
|> Map.ofArray
537537

538+
// Map of interface.Name -> List of base interfaces with event handlers
538539
let iNameToEhParents =
539540
let hasHandler (i : Browser.Interface) =
540541
iNameToEhList.ContainsKey i.Name && not iNameToEhList.[i.Name].IsEmpty
@@ -778,6 +779,10 @@ module Emit =
778779
(DomTypeToNullableTsType m.Type m.Nullable.IsSome) = expectedMType &&
779780
m.Params.Length = 1 &&
780781
(DomTypeToTsType m.Params.[0].Type) = expectedParamType
782+
let processInterfaceType iName =
783+
match getOverriddenItems ItemKind.Interface Flavor.All |> Array.tryFind (matchInterface iName) with
784+
| Some it -> iName + "<" + (it.TypeParameters |> String.concat ", ") + ">"
785+
| _ -> iName
781786

782787
/// Emit overloads for the createElement method
783788
let EmitCreateElementOverloads (m: Browser.Method) =
@@ -905,6 +910,16 @@ module Emit =
905910
| Some comment -> printLine "%s" comment
906911
| _ -> ()
907912

913+
// A covariant EventHandler is one that is defined in a parent interface as then redefined in current interface with a more specific argument types
914+
// These patterns are unsafe, and flagged as error under --strictFunctionTypes.
915+
// Here we know the property is already defined on the interface, we elide its declaration if the parent has the same handler defined
916+
let isCovariantEventHandler (p: Browser.Property) =
917+
p.Type = "EventHandler" &&
918+
iNameToEhParents.ContainsKey i.Name &&
919+
not iNameToEhParents.[i.Name].IsEmpty &&
920+
iNameToEhParents.[i.Name]
921+
|> List.exists (fun i -> iNameToEhList.ContainsKey i.Name && not iNameToEhList.[i.Name].IsEmpty && iNameToEhList.[i.Name] |> List.exists (fun e-> e.Name = p.Name))
922+
908923
let emitProperty (p: Browser.Property) =
909924
let printLine content =
910925
if conflictedMembers.Contains p.Name then Pt.PrintlToStack content else Pt.Printl content
@@ -941,6 +956,7 @@ module Emit =
941956
| Some ps ->
942957
ps.Properties
943958
|> Array.filter (ShouldKeep flavor)
959+
|> Array.filter (isCovariantEventHandler >> not)
944960
|> Array.iter emitProperty
945961
| None -> ()
946962

@@ -966,7 +982,12 @@ module Emit =
966982
// Otherwise, this is EventTarget.addEventListener, we want to keep that.
967983
let mFilter (m:Browser.Method) =
968984
matchScope emitScope m &&
969-
not (prefix <> "" && OptionCheckValue "addEventListener" m.Name)
985+
not (
986+
prefix <> "" && (
987+
(OptionCheckValue "addEventListener" m.Name) ||
988+
(OptionCheckValue "removeEventListener" m.Name)
989+
)
990+
)
970991

971992
let emitMethod flavor prefix (i:Browser.Interface) (m:Browser.Method) =
972993
let printLine content =
@@ -1049,30 +1070,43 @@ module Emit =
10491070
| _ -> ()
10501071

10511072
let EmitEventHandlers (flavor: Flavor) (prefix: string) (i:Browser.Interface) =
1073+
let getOptionsType (addOrRemove: string) =
1074+
if addOrRemove = "add" then "AddEventListenerOptions" else "EventListenerOptions"
1075+
10521076
let fPrefix =
10531077
if prefix.StartsWith "declare var" then "declare function " else ""
10541078

1055-
let emitEventHandler prefix (iParent:Browser.Interface) =
1079+
let emitTypedEventHandler (prefix: string) (addOrRemove: string) (iParent:Browser.Interface) =
10561080
Pt.Printl
1057-
"%saddEventListener<K extends keyof %sEventMap>(type: K, listener: (this: %s, ev: %sEventMap[K]) => any, useCapture?: boolean): void;"
1058-
prefix iParent.Name i.Name iParent.Name
1081+
"%s%sEventListener<K extends keyof %sEventMap>(type: K, listener: (this: %s, ev: %sEventMap[K]) => any, options?: boolean | %s): void;"
1082+
prefix addOrRemove iParent.Name i.Name iParent.Name (getOptionsType addOrRemove)
10591083

1060-
let shouldEmitStringEventHandler =
1084+
let emitStringEventHandler (addOrRemove: string) =
1085+
Pt.Printl
1086+
"%s%sEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | %s): void;"
1087+
fPrefix addOrRemove (getOptionsType addOrRemove)
1088+
1089+
let tryEmitTypedEventHandlerForInterface (addOrRemove: string) =
10611090
if iNameToEhList.ContainsKey i.Name && not iNameToEhList.[i.Name].IsEmpty then
1062-
emitEventHandler fPrefix i
1091+
emitTypedEventHandler fPrefix addOrRemove i
10631092
true
10641093
elif iNameToEhParents.ContainsKey i.Name && not iNameToEhParents.[i.Name].IsEmpty then
10651094
iNameToEhParents.[i.Name]
10661095
|> List.sortBy (fun i -> i.Name)
1067-
|> List.iter (emitEventHandler fPrefix)
1096+
|> List.iter (emitTypedEventHandler fPrefix addOrRemove)
10681097
true
10691098
else
10701099
false
10711100

1072-
if shouldEmitStringEventHandler then
1073-
Pt.Printl
1074-
"%saddEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;"
1075-
fPrefix
1101+
let emitEventHandler (addOrRemove: string) =
1102+
if tryEmitTypedEventHandlerForInterface addOrRemove then
1103+
// only emit the string event handler if we just emited a typed handler
1104+
emitStringEventHandler addOrRemove
1105+
1106+
1107+
emitEventHandler "add"
1108+
emitEventHandler "remove"
1109+
10761110

10771111
let EmitConstructorSignature flavor (i:Browser.Interface) =
10781112
let emitConstructorSigFromJson (c: InputJsonType.Root) =
@@ -1130,9 +1164,9 @@ module Emit =
11301164

11311165
let processedIName = processIName i.Name
11321166
if processedIName <> i.Name then
1133-
Pt.PrintlToStack "interface %s extends %s {" i.Name processedIName
1167+
Pt.PrintlToStack "interface %s extends %s {" (processInterfaceType i.Name) processedIName
11341168

1135-
Pt.Printl "interface %s" processedIName
1169+
Pt.Printl "interface %s" (processInterfaceType processedIName)
11361170
let finalExtends =
11371171
let overridenExtendsFromJson =
11381172
InputJson.getOverriddenItemsByInterfaceName ItemKind.Extends Flavor.All i.Name
@@ -1357,13 +1391,18 @@ module Emit =
13571391
EmitConstructor flavor i
13581392

13591393
let EmitDictionaries flavor =
1394+
13601395
let emitDictionary (dict:Browser.Dictionary) =
13611396
match dict.Extends with
1362-
| "Object" -> Pt.Printl "interface %s {" dict.Name
1363-
| _ -> Pt.Printl "interface %s extends %s {" dict.Name dict.Extends
1397+
| "Object" -> Pt.Printl "interface %s {" (processInterfaceType dict.Name)
1398+
| _ -> Pt.Printl "interface %s extends %s {" (processInterfaceType dict.Name) dict.Extends
13641399

13651400
let emitJsonProperty (p: InputJsonType.Root) =
1366-
Pt.Printl "%s: %s;" p.Name.Value p.Type.Value
1401+
let readOnlyModifier =
1402+
match p.Readonly with
1403+
| Some(true) -> "readonly "
1404+
| _ -> ""
1405+
Pt.Printl "%s%s: %s;" readOnlyModifier p.Name.Value p.Type.Value
13671406

13681407
let removedPropNames =
13691408
getRemovedItems ItemKind.Property flavor

0 commit comments

Comments
 (0)