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 Pa***efPtr<DocumentEventQueue> create(ScriptExecutionContext*);
    virtual ~DocumentEventQueue();

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

    void enqueueOrDispatchScrollEvent(Pa***efPtr<Node>, ScrollEventTargetType);

private:
    explicit DocumentEventQueue(ScriptExecutionContext*);

    void pendingEventTimerFired();
    void dispatchEvent(Pa***efPtr<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處理的流程。

說的比較模糊,僅作爲自己日後參考,同時歡迎討論。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章