web icon indicating copy to clipboard operation
web copied to clipboard

Generate mixin interfaces.

Open ykmnkmi opened this issue 8 months ago • 7 comments

Like ChildNode, DocumentOrShadowRoot and others.

ykmnkmi avatar Apr 19 '25 16:04 ykmnkmi

Great idea!

kevmoo avatar Apr 19 '25 19:04 kevmoo

We initially generated these types, but it resulted in bugs with static members: https://github.com/dart-lang/web/issues/56#issuecomment-1773532214.

We could resolve it such that we still generate the mixin, but it would only contain instance members as static members are copied to the type that mixes it in. However, that seems awkward because these types don't actually exist in the browser. For example, what should isA<DocumentOrShadowRoot>() return? The webref documentation leads me to believe these are not separate types, and all types that mix them in should treat them as if the members were directly copied. There isn't a notion of a "mixin extension type" in Dart, so copying them over was the next best idea.

srujzs avatar Apr 21 '25 17:04 srujzs

I'm guessing it's mostly useful for extension members and functions – less for is checks.

kevmoo avatar Apr 21 '25 17:04 kevmoo

I'd be curious to see a use case, but I can assume one use case is using the mixin type in absence of a union type.

The isA comment was more intended to show that introducing these types may lead to confusing behavior between is and isA. You'd have to know that the mixin name doesn't exist in the browser.

srujzs avatar Apr 21 '25 22:04 srujzs

Yeah it's tricky. I'm guessing our existing lint would handle is ChildNode but we'd have to hard-wire APIs like isA<ChildNode>() right?

kevmoo avatar Apr 21 '25 22:04 kevmoo

Yep, exactly.

srujzs avatar Apr 21 '25 22:04 srujzs

~For me, having abstract interfaces is enough~. ChildNode has useful methods like after, before, and remove, included in CharacterData (Text, Comment) and Element, which are the most commonly used classes in web frameworks:

void doSomethingOrRemove(Node child) {
  // ...
  child.remove(); // no `remove` method; add an extension, cast it and reuse Element.remove, or use JSObject.callMethod.
}

ykmnkmi avatar Apr 22 '25 05:04 ykmnkmi