dart-lang / web

Lightweight browser API bindings built around JS static interop.
https://pub.dev/packages/web
BSD 3-Clause "New" or "Revised" License
134 stars 23 forks source link

NodeFilter constants are missing #252

Open ahmednfwela opened 4 months ago

ahmednfwela commented 4 months ago

The following constants are missing from NodeFilter: https://developer.mozilla.org/en-US/docs/Web/API/TreeWalker/whatToShow note that NodeFilter is defined as JSFunction so I am not sure how these constants would be mapped.

srujzs commented 4 months ago

Ah it looks like these are callbacks with actual interfaces (seems like there's a total of 3 such callback interfaces): https://github.com/w3c/webref/blob/889fb706923c9a666c73a64545193a35cdec3983/ed/idl/dom.idl#L551C20-L551C30.

Generating an appropriate interface for this might be tricky. Naively, we can generate an extension type on JSFunction:

extension type NodeFilter._(JSFunction _) implements JSFunction {
  external static int get SHOW_ALL;
  ...
}

But then because it's no longer a typedef, users who want to use APIs that accept a NodeFilter will now need to cast/construct a NodeFilter trivially.

ahmednfwela commented 4 months ago

it looks like the spec identifies callback interface as legacy https://webidl.spec.whatwg.org/#dfn-callback-interface

Also from my limited understanding, these are interfaces that contain EXACTLY ONE function, and any number of constants

e.g.

  1. EventListener has undefined handleEvent(Event event);
  2. NodeFilter has unsigned short acceptNode(Node node); and some constants
  3. XPathNSResolver has DOMString? lookupNamespaceURI(DOMString? prefix);

from a first glance, they are very similar to dart's callable classes

so they are technically just interfaces, meaning they can be defined as

extension type NodeFilter._(JSObject _) implements JSObject {
  external static int get SHOW_ALL;
  //...
  external static int acceptNode(Node node);
  // this line is optional
  int call(Node node) => acceptNode(node);
}