先看个简单的,仅仅在body中处理的事件
通过阅读代码
1. webcore 定义了一组全局标签宏,应该是编译时候自动生成的
DEFINE_GLOBAL(AtomicString, xhtmlNamespaceURI, "")
// Tags
DEFINE_GLOBAL(QualifiedName, aTag, nullAtom, "a", xhtmlNamespaceURI);
DEFINE_GLOBAL(QualifiedName, abbrTag, nullAtom, "abbr", xhtmlNamespaceURI);
DEFINE_GLOBAL(QualifiedName, acronymTag, nullAtom, "acronym", xhtmlNamespaceURI);
DEFINE_GLOBAL(QualifiedName, addressTag, nullAtom, "address", xhtmlNamespaceURI);
DEFINE_GLOBAL(QualifiedName, appletTag, nullAtom, "applet", xhtmlNamespaceURI);
DEFINE_GLOBAL(QualifiedName, areaTag, nullAtom, "area", xhtmlNamespaceURI);
DEFINE_GLOBAL(QualifiedName, articleTag, nullAtom, "article", xhtmlNamespaceURI);
DEFINE_GLOBAL(QualifiedName, asideTag, nullAtom, "aside", xhtmlNamespaceURI);
DEFINE_GLOBAL(QualifiedName, audioTag, nullAtom, "audio", xhtmlNamespaceURI);
DEFINE_GLOBAL(QualifiedName, bTag, nullAtom, "b", xhtmlNamespaceURI);
DEFINE_GLOBAL(QualifiedName, baseTag, nullAtom, "base", xhtmlNamespaceURI);
DEFINE_GLOBAL(QualifiedName, basefontTag, nullAtom, "basefont", xhtmlNamespaceURI);
DEFINE_GLOBAL(QualifiedName, bdoTag, nullAtom, "bdo", xhtmlNamespaceURI);
DEFINE_GLOBAL(QualifiedName, bigTag, nullAtom, "big", xhtmlNamespaceURI);
DEFINE_GLOBAL(QualifiedName, blockquoteTag, nullAtom, "blockquote", xhtmlNamespaceURI);
DEFINE_GLOBAL(QualifiedName, bodyTag, nullAtom, "body", xhtmlNamespaceURI);
DEFINE_GLOBAL(QualifiedName, brTag, nullAtom, "br", xhtmlNamespaceURI);
DEFINE_GLOBAL(QualifiedName, buttonTag, nullAtom, "button", xhtmlNamespaceURI);
DEFINE_GLOBAL(QualifiedName, canvasTag, nullAtom, "canvas", xhtmlNamespaceURI);
DEFINE_GLOBAL(QualifiedName, captionTag, nullAtom, "caption", xhtmlNamespaceURI);
DEFINE_GLOBAL(QualifiedName, centerTag, nullAtom, "center", xhtmlNamespaceURI);
DEFINE_GLOBAL(QualifiedName, citeTag, nullAtom, "cite", xhtmlNamespaceURI);
DEFINE_GLOBAL(QualifiedName, codeTag, nullAtom, "code", xhtmlNamespaceURI);
DEFINE_GLOBAL(QualifiedName, colTag, nullAtom, "col", xhtmlNamespaceURI);
DEFINE_GLOBAL(QualifiedName, colgroupTag, nullAtom, "colgroup", xhtmlNamespaceURI);
DEFINE_GLOBAL(QualifiedName, datagridTag, nullAtom, "datagrid", xhtmlNamespaceURI);
DEFINE_GLOBAL(QualifiedName, datalistTag, nullAtom, "datalist", xhtmlNamespaceURI);
DEFINE_GLOBAL(QualifiedName, dcellTag, nullAtom, "dcell", xhtmlNamespaceURI);
DEFINE_GLOBAL(QualifiedName, dcolTag, nullAtom, "dcol", xhtmlNamespaceURI);
。。。。。。。。
2. 在parsetag时候
PassRefPtr HTMLParser::getNode(Token* t)
{
// Init our error handling table.
DEFINE_STATIC_LOCAL(FunctionMap, gFunctionMap, ());
if (gFunctionMap.isEmpty()) {
gFunctionMap.set(aTag.localName().impl(), &HTMLParser::nestedCreateErrorCheck);
gFunctionMap.set(addressTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
gFunctionMap.set(articleTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
gFunctionMap.set(asideTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
gFunctionMap.set(bTag.localName().impl(), &HTMLParser::nestedStyleCreateErrorCheck);
gFunctionMap.set(bigTag.localName().impl(), &HTMLParser::nestedStyleCreateErrorCheck);
gFunctionMap.set(blockquoteTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
gFunctionMap.set(bodyTag.localName().impl(), &HTMLParser::bodyCreateErrorCheck);
gFunctionMap.set(buttonTag.localName().impl(), &HTMLParser::nestedCreateErrorCheck);
gFunctionMap.set(centerTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
gFunctionMap.set(commentAtom.impl(), &HTMLParser::commentCreateErrorCheck);
gFunctionMap.set(ddTag.localName().impl(), &HTMLParser::ddCreateErrorCheck);
gFunctionMap.set(dirTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
gFunctionMap.set(divTag.localName().impl(), &HTMLParser::pCloserCreateErrorCheck);
.....
将tag和创建它们的方法关联。
3. static void createFunctionMap()
{
ASSERT(!gFunctionMap);
// Create the table.
gFunctionMap = new FunctionMap;
// Populate it with constructor functions.
addTag(aTag, anchorConstructor);
addTag(appletTag, appletConstructor);
addTag(areaTag, areaConstructor);
#if ENABLE(VIDEO)
addTag(audioTag, audioConstructor);
#endif
addTag(baseTag, baseConstructor);
addTag(basefontTag, basefontConstructor);
addTag(blockquoteTag, blockquoteConstructor);
addTag(bodyTag, bodyConstructor);
addTag(brTag, brConstructor);
addTag(buttonTag, buttonConstructor);
addTag(canvasTag, canvasConstructor);
addTag(captionTag, tablecaptionConstructor);
addTag(colTag, tablecolConstructor);
addTag(colgroupTag, tablecolConstructor);
#if ENABLE(DATAGRID)
addTag(datagridTag, datagridConstructor);
#endif
#if ENABLE(DATALIST)
addTag(datalistTag, datalistConstructor);
#endif
#if ENABLE(DATAGRID)
addTag(dcellTag, datagridcellConstructor);
#endif
#if ENABLE(DATAGRID)
addTag(dcolTag, datagridcolConstructor);
#endif
addTag(delTag, modConstructor);
addTag(dirTag, directoryConstructor);
addTag(divTag, divConstructor);
addTag(dlTag, dlistConstructor);
#if ENABLE(DATAGRID)
addTag(drowTag, datagridrowConstructor);
#endif
addTag(embedTag, embedConstructor);
addTag(fieldsetTag, fieldsetConstructor);
addTag(fontTag, fontConstructor);
addTag(formTag, formConstructor);
addTag(frameTag, frameConstructor);
addTag(framesetTag, framesetConstructor);
addTag(h1Tag, headingConstructor);
addTag(h2Tag, headingConstructor);
addTag(h3Tag, headingConstructor);
addTag(h4Tag, headingConstructor);
addTag(h5Tag, headingConstructor);
addTag(h6Tag, headingConstructor);
addTag(headTag, headConstructor);
addTag(hrTag, hrConstructor);
addTag(htmlTag, htmlConstructor);
addTag(iframeTag, iframeConstructor);
addTag(imageTag, imgToimageConstructor);
addTag(imgTag, imageConstructor);
addTag(inputTag, inputConstructor);
addTag(insTag, modConstructor);
addTag(isindexTag, isindexConstructor);
addTag(keygenTag, keygenConstructor);
addTag(labelTag, labelConstructor);
addTag(legendTag, legendConstructor);
addTag(liTag, liConstructor);
addTag(linkTag, linkConstructor);
addTag(listingTag, preConstructor);
addTag(mapTag, mapConstructor);
addTag(marqueeTag, marqueeConstructor);
addTag(menuTag, menuConstructor);
addTag(metaTag, metaConstructor);
addTag(objectTag, objectConstructor);
addTag(olTag, olistConstructor);
addTag(optgroupTag, optgroupConstructor);
addTag(optionTag, optionConstructor);
addTag(pTag, paragraphConstructor);
addTag(paramTag, paramConstructor);
addTag(preTag, preConstructor);
#if ENABLE(PROGRESS_TAG)
addTag(progressTag, progressConstructor);
#endif
addTag(qTag, quoteConstructor);
addTag(scriptTag, scriptConstructor);
addTag(selectTag, selectConstructor);
#if ENABLE(VIDEO)
addTag(sourceTag, sourceConstructor);
#endif
addTag(styleTag, styleConstructor);
addTag(tableTag, tableConstructor);
addTag(tbodyTag, tablesectionConstructor);
addTag(tdTag, tablecellConstructor);
addTag(textareaTag, textareaConstructor);
addTag(tfootTag, tablesectionConstructor);
addTag(thTag, tablecellConstructor);
addTag(theadTag, tablesectionConstructor);
addTag(titleTag, titleConstructor);
addTag(trTag, tablerowConstructor);
addTag(ulTag, ulistConstructor);
#if ENABLE(VIDEO)
addTag(videoTag, videoConstructor);
#endif
addTag(xmpTag, preConstructor);
}
当html页面本身被下载后, webkit开始接续html,当解析到上述符合名字的node时候会调用,注册的factory创建节点。然后创建节点后开始解析节点的属性,碰到上述map中定义的属性那么久创建属性的时间listener
(对本例而言)。
上图就是html下载后的parsehtml时候发现有个title的节点,然后常见这样一个节点类。
以此类推最后会发现一个body的节点。
当常见body节点后,parsemappedattrhi触发创建节点的属性事件接受者。
然后发现创建的eventlistener被加到domwindow 的eventtarget内部的一个map中(这个有点特殊,没有加到htmlbodyelement自己的eventtarget中,不过这个是特定的时事件处理模式,即onload,onunload等是作为document的事件进行处理的;如果将onclick加到body后那么这个listener还是在element上的)
这儿差异在于,input代表为htmlelement,而每个htmlelement 均最终派生再 node 而每个node都派生自eventtarget,这个不太同于body内的onload事件处理器。
...