webkit学习之event

学习event对象:

Event是在WebCore/dom/Event.h中定义,比较关注的是成员变量EventTarget类型的指针target,根据target调用每个event的handle处理。在应用中设计一个子类继承EventTarget,并在其中添加一个成员变量m_result,可以完成Event传递参数的使命。在每个event被create出来后,一般情况下都会设置把target变量初始化一下(包括把m_result初始化),然丢到一个eventqueue中等待处理。

对于Event类型中的其他变量还没有学习到,目前还没有用到。

JavaScript运行过程中event流程:

我们知道html中的JavaScript的运行其实是通过Frame类中的ScriptController接口完成的。而实际运行的代码是WebCore目录中的cpp代码(这个过程以后会介绍),而在JavaScript中应用Eevnt对象,也就是在WebCore中的对应cpp代码中使用Event对象。比如,在html文件中对一个button定义onclick处理,这里就牵扯到Event的处理过程。在JavaScript运行过程也会涉及到很多Event处理,比如,在JS中对localStorage的操作,都是由Event完成。由于最近在学习IndexDB相关,所以就以这个为例子,介绍一下JS后台程序如何使用Event对象。

Frame类中包含了一个Document指针,而Document是ScriptExecutionContext的子类,它保存了一个DocumentEventQueue类型的指针。而DocumentEventQueue又是EventQueue的子类,EventQueue中有一个Event对象的hash表。DocumentEventQueue定义如下:

class DocumentEventQueue : public RefCounted<DocumentEventQueue>, public EventQueue {
public:
    enum ScrollEventTargetType {
        ScrollEventDocumentTarget,
        ScrollEventElementTarget
    };

    static PassRefPtr<DocumentEventQueue> create(ScriptExecutionContext*);
    virtual ~DocumentEventQueue();

    // EventQueue
    virtual bool enqueueEvent(PassRefPtr<Event>) OVERRIDE;
    virtual bool cancelEvent(Event*) OVERRIDE;
    virtual void close() OVERRIDE;

    void enqueueOrDispatchScrollEvent(PassRefPtr<Node>, ScrollEventTargetType);

private:
    explicit DocumentEventQueue(ScriptExecutionContext*);

    void pendingEventTimerFired();
    void dispatchEvent(PassRefPtr<Event>);

    OwnPtr<DocumentEventQueueTimer> m_pendingEventTimer;
    ListHashSet<RefPtr<Event> > m_queuedEvents;
    HashSet<Node*> m_nodesWithQueuedScrollEvents;
    bool m_isClosed;

    friend class DocumentEventQueueTimer;   
};

通过调用enqueueEvent接口把Event放进queuedEvents中,同时也会通过pendingEventTimer运行pendingEventTimerFired函数,调用dispatchEvent函数,调用EventTarget的dispatchEvent函数,所有的Event都会走这么一个流程。

对IndexDB来讲,所有对DB的操作都会转化成一个Request对象,这个对象继承于EventTarget。当JS中执行了一个DB的操作,发起一个request,执行成功(可以理解为是允许执行),调用request的onSuccess,在这个函数里会首先创建一个Event,然后把target设置为自己,然后调用把context转换为Document对象,调用document的Enqueue函数,然后走上述的Document对应的Event流程,最终调到request的dispatchEvent函数,这个函数中调用EventDispatcher::dispatch去fire这个event的listener,然后完成应该做的工作。这样就走完了一套JS发起一个请求,最终到event处理的流程。

说的比较模糊,仅作为自己日后参考,同时欢迎讨论。

你可能感兴趣的:(学习)