Hi,
    I post this message to discuss the initial design of DOM Events
module. Generally, the whole Events model will be implemented at
libdom/src/events. And there are four types of Interface, they are
DocumentEvent, EventTarget, Event and EventListener. I will describe
how I will implement these four types of interfaces.

1. DocumentEvent. This interface is used to create event objects and
will be implemented as part of dom_document. So, now, dom_document at
least need to implement two different Interfaces: Document and
DocumentEvent. And this situation will occur again when we deal with
other Interfaces such as EventTarget later. So, we should figure out a
common way to let one type of C struct to implement multiple
Interface. Generally, I advise a method below:

struct dom_document_event {
    dom_event_listener * (*default_action)(lwc_string *node_name,
lwc_string *event_type) da;

    /* Nearlly all elements have its default handler, such as, an
Anchor element will cause a new page opened when click event occur.
And I think Netsurf is the approtiate handler for this event. So, I
think it is better to let the client of our dom events module pass a
function to us which we use to fetch the default hanlder for all
default action */
};

And then add a new member to dom_document.

struct dom_document {
    /* original members */
    struct dom_document_event de;
};

And the method createEvent will be defined as macro like:

#define DOM_DOCUMENT_EVENT(d)  &(d->de)

#define dom_document_event_create_event(dt, name)
_dom_document_event_create_event(DOM_DOCUMENT_EVENT(d), name)

This makes all functions of dom_document_event accept
dom_document_event * as first param, and I think this is better. To
access the dom_document which contain the dom_document_event, we can :

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#define DOM_DOCUMENT(de) ((struct dom_document *) (de -
offsetof(dom_document, de)))

So, that's the DocumentEvent Interface.

2. EventTarget. This interface will be implemented in
dom_node_internal, using the same method with 1. We got:

sturct dom_node_internal {
    /* original members */
    struct dom_event_target et;
};

And all the Macroes above are similar.

3. Event and its subclasses. Just as Node and its subclasses, I will
use the same method to implement these classes. But because there is
no overriden functions, I want to use no vtable in Events class tree.
And change it to use vtable when  necessary.

4. EventListener. Something like:

struct dom_event_listener {
    void *private;
    bool (*handle)(dom_event *e, void *private) handler;
};


Boostrap:
The Events module is used to provide a mechanism to dispatch the Event
on the DOM tree, for most cases, it need its client to provide some
default action for certain kind of elements (just like what 1 said).
This may require our client to pass a function pointer (just like pass
in the allocator) when create the document. So, the create_document
method may need to be added a new param:

create_document(dom_implementation *impl,
            struct dom_string *namespace,
            struct dom_string *qname,
            struct dom_document_type *doctype,
            dom_alloc alloc, void *pw, struct lwc_context_s *ctx,
            dom_event_listener * (*default_action)(lwc_string
*node_name, lwc_string *event_type) da,
            struct dom_document **doc);


That's all about my idea of Events model, please post any questions
about this. And any advice is welcomed!

Regards!
Bo

Reply via email to