Refactor of event (breaking change in upcoming 0.4) #50
Replies: 2 comments 2 replies
-
I like the direction - I have that feeling of interface overload too. It also makes harder to navigate the code, when I try to understand the implementation that was run during debugging What you propose makes sense to me. |
Beta Was this translation helpful? Give feedback.
-
And even further insights revealed that I can eliminate the necessity to use a "constructor", i.e., the The solution was a unique ID that is generated from the constructor. But the id can just be lazily generated, so the necessity for the constructor call is eliminated. This will change in the next release, but shouldn't be breaking. |
Beta Was this translation helpful? Give feedback.
-
This is an early announcement about a breaking change in the event model.
This will only affect code if you are explicitly dispatching events from Go code, or actively adding event listeners (should be a minor change of type here).
If you are just let events live on the JavaScript side of things, there shouldn't be any changes required.
Reason for change.
A major problem in this project was modelling a "object oriented" model in a Go, that isn't object-oriented in that sense.
A solution was to rely heavily on embedding, but as any function returning e.g. a
Node
can return any "subclass" of Node, the return type is an interface, not a type, as the type cannot be known in advance.The DOM specifications also exhibit an inheritance model for events, e.g., a
UIEvent
inheritsEvent
,MouseEvent
inheritsUIEvent
. However, all extra properties on the event types are part of the 2nd constructor argument, So aUIEvent
takes aUIEventInit
constructor argument,MouseEvent
takes aMouseEventInit
, etc.But there are two parts of the solution that annoys me:
Go "inheritance" doesn't need to reflect JavaScript inheritance.
But I realized that while the JavaScript side must exhibit an inheritance hierarchy of event classes, the Go implementation doesn't, as long as it has enough information present.
All classes in the
Event
class hierarchy accepts two constructor args. The "type", i.e. the event type, and anEventInit
dictionary specification. Each event subclass has a corresponding event init specification, and they share an identical tree of "subclasses".End the extra properties that exist on the event subclasses are the properties on the
EventInit
dictionary.So I could just create a single
Event
type which has anEventInit
, being an interface, and pass recreate the event specialisation in theInit
types. The JavaScript wrapping layer can check the type of theEventInit
to determine which concrete JS class to return.All event handlers not receive an
*Event
with the event being a struct type, rather than an interface.The
Event
as well asEventTarget
also moved to anevents
subpackage (but will probably be renamed toevent
before release), as it gives better names, e.g. a new event becomesevent.New
- natural Go code. Some function prefixes could also be removed as the existence in theevents
package gives enough context, but in thedom
package, the general purpose names would pollute scope and be unclear of the purpose in the scope of the package.Footnotes
I'm wondering if a strategy pattern would have made sense for the DOM node tree, though that would lead to other problems. ↩
Beta Was this translation helpful? Give feedback.
All reactions