Mozilla研究—XUL窗口创建和事件处理
mozilla是一个以浏览器为中心的软件平台,它在我们平台中占有重要地位。我们用它来实现WEB浏览器、WAP浏览器、邮件系统、电子书和帮助阅读器等应用程序。为此,我最近花了不少时间去阅读mozilla的代码和文档,我将写一系列的BLOG作为笔记,供有需要的朋友参考。本文介绍窗口创建和事件处理。
窗口创建
1. 对于提示窗口,像javascript中的alert/confirm等函数所打开的。其过程如下:nsPromptService::DoDialogànsWindowWatcher::OpenWindowànsXULWindow::ShowModal。如果想要定制提示窗口的行为,比如在命令行下提示,可以重新实现nsIPromptService2/nsPIPromptService接口。
2. 对于正常窗口,其创建过程如下:nsWindowWatcher::OpenWindowàWindowCreator::CreateChromeWindow2ànsWindowConstructor。
窗口关闭
1. 在javascript中调用close函数关闭窗口。
2. 经XPConnect调用nsGlobalWindow::Close。
3. nsGlobalWindow::Close调用nsGlobalWindow::ReallyCloseWindow去关闭窗口。
事件注册
1. 在XUL文档解析完成之后,nsXULDocument::PrepareToWalk去创建所有的nsXULElement。
2. nsXULElement::Create调用nsXULElement::AddScriptEventListener去注册事件处理函数。
3. nsXULElement::AddScriptEventListener调用nsEventListenerManager:: AddScriptEventListener去注册事件处理函数。
4. nsEventListenerManager::AddScriptEventListener经nsJSContext,最终调用NS_NewJSEventListener去把javascript事件处理函数包装成nsIDOMEventListener,并注册到nsEventListenerManager中。
事件分发
1. nsWindow.cpp 中的xxx_event_cb之类的函数把GTK+的事件转发给nsWindow::OnXxxEvent函数。
2. nsCommonWidget::DispatchEvent把事件转发View注册的回调函数HandleEvent。
3. nsView.cpp: HandleEvent通过事件的Widget找到当前的View,再找到对应的ViewManager,然后通过nsViewManager::DispatchEvent分发消息。
4. nsViewManager通过PresShell把消息转发到对应的nsXULElement。
5. nsXULElement通过nsEventListenerManager把消息转发到nsJSEventListener。
6. nsJSEventListener::HandleEvent再经javascript解释器调用javascript的事件处理函数。